示例#1
0
 /// <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 日志注入