- 1、自定義認證中間件 JwtTokenAuth
- 2、Startup
- Configure下:
-
if (env.IsDevelopment()) { GlobalContext.SystemConfig.Debug = true; app.UseDeveloperExceptionPage(); } else { app.UseDeveloperExceptionPage(); } app.UseCors("CorsPolicy"); app.UseAuthentication(); app.UseMiddleware<JwtTokenAuth>(); string resource = Path.Combine(env.ContentRootPath, "Resource"); FileHelper.CreateDirectory(resource); app.UseStaticFiles(new StaticFileOptions { OnPrepareResponse = GlobalContext.SetCacheControl }); app.UseStaticFiles(new StaticFileOptions { RequestPath = "/Resource", FileProvider = new PhysicalFileProvider(resource), OnPrepareResponse = GlobalContext.SetCacheControl }); app.UseMiddleware(typeof(GlobalExceptionMiddleware)); app.UseCors(builder => { builder.WithOrigins(GlobalContext.SystemConfig.AllowCorsSite.Split(',')).AllowAnyHeader().AllowAnyMethod().AllowCredentials(); }); app.UseSwagger(c => { c.RouteTemplate = "api-doc/{documentName}/swagger.json"; }); app.UseSwaggerUI(c => { c.RoutePrefix = "api-doc"; c.SwaggerEndpoint("v1/swagger.json", "YiSha Api v1"); }); app.UseRouting(); app.UseCors(cfg => { cfg.AllowAnyOrigin(); cfg.AllowAnyMethod(); cfg.AllowAnyHeader(); }); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute("default", "{controller=ApiHome}/{action=Index}/{id?}"); }); GlobalContext.ServiceProvider = app.ApplicationServices; if (!GlobalContext.SystemConfig.Debug) { new JobCenter().Start(); // 定時任務 }
ConfigureServices下:
-
#region Cors 跨域 services.AddCors(options => options.AddPolicy("CorsPolicy", builder => { builder.AllowAnyMethod() .SetIsOriginAllowed(_ => true) .AllowAnyHeader() .AllowCredentials(); })); #endregion #region Swagger services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "Supervise Api", Version = "v1" }); //添加中文註釋 var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location); var commentsFileName = "YiSha.Admin.WebApi.xml"; var xmlPath = Path.Combine(basePath, commentsFileName); //默認的第二個參數是false,這個是controller的註釋 c.IncludeXmlComments(xmlPath, true); //添加Model類的註釋 var modelfilename = "YiSha.Model.xml"; var modelxmlpath = Path.Combine(basePath, modelfilename); c.IncludeXmlComments(modelxmlpath); c.DocInclusionPredicate((docName, description) => true); //services.AddAuthorization(options => //{ // options.AddPolicy("Client", policy => policy.RequireRole("Client").Build()); // options.AddPolicy("Admin", policy => policy.RequireRole("Admin").Build()); // options.AddPolicy("SystemOrAdmin", policy => policy.RequireRole("Admin", "System")); //}); #region Token綁定到ConfigureServices c.AddSecurityRequirement(new OpenApiSecurityRequirement() { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" }, Scheme = "oauth2", Name = "Bearer", In = ParameterLocation.Header, }, new List<string>() } }); //添加設置Token的按鈕 c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { Description = "Bearer {token}", Name = "Authorization",// jwt默認的參數名稱 In = ParameterLocation.Header, // jwt默認存放Authorization信息的位置(請求頭中) Type = SecuritySchemeType.ApiKey, Scheme = "Bearer" }); #endregion }); #endregion #region JWT var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration["Audience:Secret"])); services.AddAuthentication("Bearer").AddJwtBearer(o => { o.TokenValidationParameters = new TokenValidationParameters { //是否開啓密鑰認證和key值 ValidateIssuerSigningKey = true, IssuerSigningKey = signingKey, //是否開啓發行人認證和發行人 ValidateIssuer = true, ValidIssuer = Configuration["Audience:Issuer"], //是否開啓訂閱人認證和訂閱人 ValidateAudience = true, ValidAudience = Configuration["Audience:Audience"], //認證時間的偏移量 //注意這是緩衝過期時間,總的有效時間等於這個時間加上jwt的過期時間,如果不配置,默認是5分鐘 ClockSkew = TimeSpan.FromSeconds(10800), //是否開啓時間認證 ValidateLifetime = true, //是否該令牌必須帶有過期時間 RequireExpirationTime = true, }; }); #endregion
- 3、appsettings
"Audience": { "Secret": "11111111111111", "Issuer": "222222222", "Audience": "Nobody" },
-
4、 Controller增加
-
[ApiController]
[ApiController][AuthorizeFilter]
[Authorize] - 5、AuthorizeFilter擴展
-
string token = context.HttpContext.Request.Headers["Authorization"].ParseToString(); if (!string.IsNullOrEmpty(token)) { token =token.Replace("Bearer ", ""); } //token = (context.HttpContext.Request.Headers).HeaderAuthorization; OperatorInfo user = await Operator.Instance.Current(token); if (user != null) { // 根據傳入的Token,設置CustomerId if (context.ActionArguments != null && context.ActionArguments.Count > 0) { PropertyInfo property = context.ActionArguments.FirstOrDefault().Value.GetType().GetProperty("Token"); if (property != null) { property.SetValue(context.ActionArguments.FirstOrDefault().Value, token, null); } switch (context.HttpContext.Request.Method.ToUpper()) { case "GET": break; case "POST": property = context.ActionArguments.FirstOrDefault().Value.GetType().GetProperty("CustomerId"); if (property != null) { property.SetValue(context.ActionArguments.FirstOrDefault().Value, user.UserId, null); } break; } } } else { string actionName = ((ControllerActionDescriptor)context.ActionDescriptor).ActionName; bool exists = ((IList)IgnoreToken).Contains(actionName); if (!exists) { TData obj = new TData(); obj.Message = "抱歉,沒有登錄或登錄已超時"; obj.Tag = 10; context.Result = new JsonResult(obj); return; } }