diff --git a/HttpClientStudy.Model/Account.cs b/HttpClientStudy.Model/Account.cs index 9beada5..fabf5c2 100644 --- a/HttpClientStudy.Model/Account.cs +++ b/HttpClientStudy.Model/Account.cs @@ -19,5 +19,7 @@ /// 密码 /// public string? Password { get; set; } + + public string Role { get; set; } = "Dev"; } } diff --git a/HttpClientStudy.WebApp/Controllers/AccountController.cs b/HttpClientStudy.WebApp/Controllers/AccountController.cs index feee841..7d68aa9 100644 --- a/HttpClientStudy.WebApp/Controllers/AccountController.cs +++ b/HttpClientStudy.WebApp/Controllers/AccountController.cs @@ -1,13 +1,29 @@ -using Microsoft.AspNetCore.Authorization; +using System.IdentityModel.Tokens.Jwt; +using System.Net.Http.Headers; +using System.Security.Claims; +using System.Text; + +using HttpClientStudy.Model; +using HttpClientStudy.WebApp.Models; + +using Microsoft.AspNetCore.Authentication.Cookies; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.IdentityModel.Tokens; namespace HttpClientStudy.WebApp.Controllers { + /// + /// 账号控制器 + /// [Route("api/[controller]/[action]")] [ApiController] public class AccountController : ControllerBase { + /// + /// 构造 + /// public AccountController() { } /// @@ -30,9 +46,80 @@ namespace HttpClientStudy.WebApp.Controllers /// [AllowAnonymous] [HttpGet] - public IActionResult GetToken() + public IActionResult GetToken(string userName, string password) + { + var account = new Account() { Id = 1, Name = userName, Password = password, Role = "Admin" }; + + var principal = CreateClaimsPrincipal(account); + var token = CreateJwtToken(principal.Claims.ToList()); + + var data = new { Id = account.Id, Account = account.Name, Role = account.Role, Token = token }; + + var result = BaseResultUtil.Success(data); + return new JsonResult(result); + } + + /// + /// 获取Token + /// + /// + [AllowAnonymous] + [HttpPost] + public IActionResult GetToken(LoginAccount vm) { - return new JsonResult(new { Code = 1, Message = "", Token = "a.b.c" }); + var account = new Account() { Id = 1, Name = vm.Account, Password = vm.Password, Role = "Admin" }; + + var principal = CreateClaimsPrincipal(account); + var token = CreateJwtToken(principal.Claims.ToList()); + + var data = new { Id = account.Id, Account = account.Name, Role = account.Role, Token = token }; + + var result = BaseResultUtil.Success(data); + return new JsonResult(result); + } + + /// + /// 生成ClaimsPrincipal + /// + private ClaimsPrincipal CreateClaimsPrincipal(Account account) + { + List claims = new List + { + new Claim("ID", account.Id.ToString()), + new Claim("Name",account.Name??""), + new Claim("Password", account.Password??"123123"), + new Claim("Role",account.Role), + }; + + ClaimsIdentity identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); + ClaimsPrincipal principal = new ClaimsPrincipal(identity); + + return principal; + } + + /// + /// 生成JwtToken + /// + private string CreateJwtToken(List claims) + { + //生成Jwt + //jwtTokenOptions 是通过配置获取上面配置的参数信息 + var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("0123456789abcdefghigklmnopqrstdf41sadfweqtdfghsdfgsdfweqr")); + var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); + //令牌 + var expires = DateTime.Now.AddDays(1); + var token = new JwtSecurityToken + ( + issuer: "WWW.WANGGAOFENG.CN", + audience: "WWW.WANGGAOFENG.CN", + claims: claims, + notBefore: DateTime.Now, + expires: expires, + signingCredentials: credentials + ); + string jwtToken = new JwtSecurityTokenHandler().WriteToken(token); + + return jwtToken; } } } diff --git a/HttpClientStudy.WebApp/Controllers/SimpleController.cs b/HttpClientStudy.WebApp/Controllers/SimpleController.cs new file mode 100644 index 0000000..f71fb99 --- /dev/null +++ b/HttpClientStudy.WebApp/Controllers/SimpleController.cs @@ -0,0 +1,34 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace HttpClientStudy.WebApp.Controllers +{ + /// + /// 简单接口 控制器 + /// + [Route("api/[controller]/[action]")] + [ApiController] + public class SimpleController : ControllerBase + { + private ILogger _logger; + + /// + /// 构造 + /// + public SimpleController(ILogger logger) + { + _logger = logger; + } + + /// + /// 获取账号 + /// + /// + [HttpGet] + public IActionResult GetAccount() + { + var reslut = BaseResultUtil.Success("操作成功"); + return Ok(reslut); + } + } +} diff --git a/HttpClientStudy.WebApp/HttpClientStudy.WebApp.csproj b/HttpClientStudy.WebApp/HttpClientStudy.WebApp.csproj index d0856be..a9744aa 100644 --- a/HttpClientStudy.WebApp/HttpClientStudy.WebApp.csproj +++ b/HttpClientStudy.WebApp/HttpClientStudy.WebApp.csproj @@ -1,15 +1,17 @@ - + net8.0 enable enable true + true + diff --git a/HttpClientStudy.WebApp/Models/UserForToken.cs b/HttpClientStudy.WebApp/Models/LoginAccount.cs similarity index 94% rename from HttpClientStudy.WebApp/Models/UserForToken.cs rename to HttpClientStudy.WebApp/Models/LoginAccount.cs index f543136..de63b56 100644 --- a/HttpClientStudy.WebApp/Models/UserForToken.cs +++ b/HttpClientStudy.WebApp/Models/LoginAccount.cs @@ -6,7 +6,7 @@ namespace HttpClientStudy.WebApp.Models /// /// 获取Token 请求类 /// - public class UserForToken + public class LoginAccount { /// /// 账号 diff --git a/HttpClientStudy.WebApp/Program.cs b/HttpClientStudy.WebApp/Program.cs index 6edcd90..4ca0d05 100644 --- a/HttpClientStudy.WebApp/Program.cs +++ b/HttpClientStudy.WebApp/Program.cs @@ -1,33 +1,179 @@ +using System.Text; + +using Microsoft.AspNetCore.Authentication.Cookies; +using Microsoft.AspNetCore.Http.Features; +using Microsoft.IdentityModel.Tokens; +using Microsoft.OpenApi.Models; + namespace HttpClientStudy.WebApp { + /// + /// HttpClientѧϰWebAPIĿ + /// public class Program { + /// + /// Main + /// + /// public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); - // Add services to the container. - + #region ע builder.Services.AddControllers(); - // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); - builder.Services.AddSwaggerGen(); - var app = builder.Build(); + //Sessionм + builder.Services.AddDistributedMemoryCache(); - // Configure the HTTP request pipeline. - if (app.Environment.IsDevelopment()) + //Session + builder.Services.AddSession(option => { - app.UseSwagger(); - app.UseSwaggerUI(); - } + option.Cookie.Name = "HttpClientStudy"; + option.IOTimeout = TimeSpan.FromHours(1); + option.IdleTimeout = TimeSpan.FromHours(1); + }); - app.UseAuthorization(); + //Formύѡ + builder.Services.Configure(options => + { + //options.BufferBody = true; + options.MultipartBodyLengthLimit = long.MaxValue; + options.MultipartBoundaryLengthLimit = int.MaxValue; + options.MultipartHeadersCountLimit = int.MaxValue; + options.MultipartHeadersLengthLimit = int.MaxValue; + }); + + //Swagger + builder.Services.AddSwaggerGen(setup => + { + #region Swaggerĵ + //nameΪSwaggerUISwaggerEndpointе{documentName} + //߱뱣һ£쳣 + setup.SwaggerDoc(name: "v1", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "HttpClientѧϰ", Version = "1" }); + #endregion + + #region xmlע + var xmlCommentFiles = System.IO.Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "HttpClientStudy.*.xml", System.IO.SearchOption.TopDirectoryOnly); + foreach (var xmlFile in xmlCommentFiles) + { + //includeControllerXmlCommentsǷÿϵxmlע + setup.IncludeXmlComments(filePath: xmlFile, includeControllerXmlComments: true); + + setup.UseInlineDefinitionsForEnums(); + } + #endregion + + #region ýӿAuthȨť + setup.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme + { + Description = "BearerTokenBearer {Token}", + + //jwtĬϵIJ + Name = "Authorization", + + //jwtĬϴ Authorization Ϣλã˴Ϊͷ + In = ParameterLocation.Header, + + //֤ͣ˴ʹApi Key + Type = SecuritySchemeType.ApiKey + }); + #endregion + #region ָӦ÷Χ + setup.AddSecurityRequirement(new OpenApiSecurityRequirement + { + { + new OpenApiSecurityScheme + { + Reference = new OpenApiReference + { + Id = "Bearer", + Type = ReferenceType.SecurityScheme + } + }, + new List() + } + }); + #endregion + + //ע + setup.EnableAnnotations(); + }); + + //Cors + builder.Services.AddCors(option => + { + option.AddPolicy("AllowAll", builder => + { + builder.SetIsOriginAllowed(_ => true).AllowAnyMethod().AllowAnyHeader().AllowCredentials(); + }); + }); + + //֤ + builder.Services //֤ܹ + .AddAuthentication(authOption => + { + authOption.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme; + authOption.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme; + authOption.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme; + authOption.DefaultSignOutScheme = CookieAuthenticationDefaults.AuthenticationScheme; + authOption.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; + }) + //Cookie֤ + .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, option => + { + option.Cookie.Name = ".eds.editor.cookie.authentication.oa2";//ô洢û¼ϢûTokenϢCookie + option.Cookie.HttpOnly = true;//ô洢û¼ϢûTokenϢCookie޷ͨͻű(JavaScript)ʵ + option.ExpireTimeSpan = TimeSpan.FromDays(3);// ʱ + option.SlidingExpiration = true;// ǷڹʱʱԶ + option.LoginPath = "/Account/Login"; + option.LogoutPath = "/Account/LoginOut"; + //option.AccessDeniedPath = "/Account/Login"; + }) + //֤ + .AddJwtBearer(option => + { + option.TokenValidationParameters = new TokenValidationParameters + { + ValidIssuer = "WWW.WANGGAOFENG.CN", + ValidAudience = "WWW.WANGGAOFENG.CN", + ValidateIssuer = true, + ValidateLifetime = true, + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("0123456789abcdefghigklmnopqrstdf41sadfweqtdfghsdfgsdfweqr")), + + //ʱ䣬ܵЧʱʱjwtĹʱ + ClockSkew = TimeSpan.FromSeconds(0) + }; + }); + + //Ȩ + builder.Services.AddAuthorization(); + #endregion + + var app = builder.Build(); + + #region Httpܵ + + app.UseSwagger(); + app.UseSwaggerUI(setup => + { + setup.EnableDeepLinking(); + setup.DisplayRequestDuration(); + setup.ShowCommonExtensions(); + setup.ShowExtensions(); + setup.EnableFilter(); + }); + app.UseCors("AllowAll"); + app.UseAuthorization(); app.MapControllers(); + app.UseAuthorization(); + #endregion + app.Run(); } }