/// <summary> /// 设置配置文件 /// </summary> /// <param name="section"></param> public static void SetJwtConfig(JwtConfig section) { _jwtConfig = section; }
/// <summary> /// /// </summary> /// <param name="services"></param> /// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddControllers(); AppSettings.SetAppSetting(Configuration.GetSection("AppSettings")); //services.AddDbContext<FamilyRelationshipContext>(options => //options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); #region Swagger配置 services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "FRS.WebApi", Version = "v1" }); c.SwaggerDoc("v2", new OpenApiInfo { Title = "FRS.WebApi", Version = "v2" }); // API 分组 // 当一个controller中出现多个[httpPost]/[httpGet]时,默认使用第一个 // 正确的情况是一个controller中只能包含一个get/post/put/delete,尽管多个get出现的时候是可以的,但是Swagger并不支持这种做法, // 而是建议将多个action 拆分成多个controller c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First()); // 显示导出函数<summary>说明 // 1.生成属性中生成xml // 2.c.IncludeXmlComments var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); c.IncludeXmlComments(xmlPath); //Swagger增加自定义输入UI //c.OperationFilter<AuthTokenHeaderParameter>(); c.OperationFilter <ApiVersionHeaderParameter>(); //在UI加入授权认证按钮 c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { Description = "授权认证, 输入Bearer {token}(注意两者之间是一个空格) \"", Name = "Authorization", //jwt默认的参数名称 In = ParameterLocation.Header, //jwt默认存放Authorization信息的位置(请求头中) Scheme = "Bearer", Type = SecuritySchemeType.ApiKey, BearerFormat = "JWT" }); //把所有方法配置为增加bearer头部信息 //每个API方法后,会有一个锁的标志,表明该方法会传递bearer token。 var securityRequirement = new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } }, new string[] {} } }; c.AddSecurityRequirement(securityRequirement); // 给Swagger配置FileUploadOperation c.OperationFilter <FileUploadOperation>(); }); #endregion #region 添加 jwt 认证 services.Configure <JwtConfig.JwtConfig>(Configuration.GetSection("JwtConfig")); var jwtConfig = new JwtConfig.JwtConfig(); Configuration.Bind("JwtConfig", jwtConfig); GenerateJwt.SetJwtConfig(jwtConfig); services.AddAuthentication(option => { //认证middleware配置 option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; //默认方案 option.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { //注意这是缓冲过期时间,总的有效时间等于这个时间加上jwt的过期时间,如果不配置,默认是5分钟 ClockSkew = TimeSpan.FromSeconds(4), //Token颁发机构 ValidIssuer = jwtConfig.Issuer, //颁发给谁 ValidAudience = jwtConfig.Audience, ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, //是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比 //这里的key要进行加密 IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtConfig.SecretKey)), }; options.Events = new JwtBearerEvents { OnAuthenticationFailed = context => { // 如果过期,则把添加到,返回头信息中 if (context.Exception.GetType() == typeof(SecurityTokenExpiredException)) { context.Response.Headers.Add("Token-Expired", "true"); // 必须加入Access-Control-Allow-* ,在有跨域认证的请求中加入,否则当token失效后,会返回跨域错误 context.Response.Headers.Add("Access-Control-Allow-Credentials", "true"); string Origin = context.Request.Headers["origin"]; context.Response.Headers.Add("Access-Control-Allow-Origin", Origin); // 定义在token失效后的返回数据中,允许跨域请求读取的headers的标签 context.Response.Headers.Add("Access-Control-Allow-Headers", "Token-Expired"); context.Response.Headers.Add("Access-Control-Expose-Headers", "Token-Expired,Content-Type"); } return(Task.CompletedTask); } }; }); #endregion #region json字符配置 //配置 .NET Core WebApi中返回 json 数据首字母大小写保留字段原始大小写, 不配置的情况下默认首字母小写 services.AddControllers().AddJsonOptions(config => { config.JsonSerializerOptions.PropertyNamingPolicy = null; }); //在swagger中将枚举显示为字符串 services.AddControllers().AddJsonOptions(options => options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter())); #endregion # region 日志注入