protected void Application_Start()
 {
     AutoMapperConfig.AutoMapperRegister();
     AreaRegistration.RegisterAllAreas();
     FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
     RouteConfig.RegisterRoutes(RouteTable.Routes);
     BundleConfig.RegisterBundles(BundleTable.Bundles);
 }
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            ContainerConfig.RegisterContainer(GlobalConfiguration.Configuration);

            AntiForgeryConfig.UniqueClaimTypeIdentifier = "name";
            AutoMapperConfig.AutoMapperRegister();
            ViewEngines.Engines.Clear();
            ViewEngines.Engines.Add(new MultiLanguageViewEngine());
        }
예제 #3
0
        /// <summary>
        ///  This method gets called by the runtime. Use this method to add services to the container.
        ///  侧重于注册或者添加支持某个组件
        ///  当你需要用到某个第三方组件时,在这里添加之后就可以使项目支持了
        ///  比如:要想使项目支持跨域时, 添加相应包之后,就需要在这里使用services.AddCors 添加组件支持
        ///  再比如:做认证授权时,想要使用第三方JWT组件生成token之类的内容时,也需要在这里添加相关支持
        ///  再比如:读取配置文件时,也需要在这里做相应操作
        ///  等等。。。
        ///  它就类似一台组装台式机,当需要硬盘时,在这里安装硬盘的注册支持就可以使用;当需要内存条时,同样在这里注册支持才能使用
        /// </summary>
        /// <param name="services"></param>
        public void ConfigureServices(IServiceCollection services)
        {
            //注册控制器
            services.AddControllers(options =>
            {
                options.Filters.Add(typeof(CustomExceptionsFilter));   //全局异常过滤器注册(全局生效)
            })
            //全局配置Json
            .AddNewtonsoftJson(options =>
            {
                //忽略循环引用
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                //不使用驼峰样式的key
                options.SerializerSettings.ContractResolver = new DefaultContractResolver();
                //设置本地时间而非UTC时间
                options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
            });

            #region 配置文件
            //方式1
            //读取配置文件appsettings.json,将自定义节点绑定到DBConfig类中,在任意地方直接使用
            //配置文件更新,绑定的值不会实时更新
            SystemContext.dbConfig  = Configuration.GetSection("DBConfig").Get <DBConfig>();
            SystemContext.jwtConfig = Configuration.GetSection("JwtAuthorizeConfig").Get <JwtAuthorizeConfig>();

            //方式2
            //将DBConfig对象注册到Service中,这样可以在Controller中注入使用
            //配置文件更新,绑定的值会实时更新
            services.Configure <DBConfig>(Configuration.GetSection("DBConfig"));

            #endregion

            #region JWT认证
            //注册认证(使用JWT认证)
            var symmetricKeyAsBase64 = SystemContext.jwtConfig.Secret;
            var keyByteArray         = Encoding.ASCII.GetBytes(symmetricKeyAsBase64);
            var signingKey           = new SymmetricSecurityKey(keyByteArray);
            var Issuer   = SystemContext.jwtConfig.Issuer;   //发布人
            var Audience = SystemContext.jwtConfig.Audience; //订阅人
            services.AddAuthentication(o =>
            {
                o.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
                //o.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                //o.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(opetion =>
            {
                //认证规则
                opetion.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,       //是否开启密钥认证
                    IssuerSigningKey         = signingKey, //密钥

                    ValidateIssuer = true,
                    ValidIssuer    = Issuer,   //发行人

                    ValidateAudience = true,
                    ValidAudience    = Audience,                      //订阅人

                    ValidateLifetime      = true,                     //验证生命周期
                    ClockSkew             = TimeSpan.FromSeconds(30), //exp过期时允许的偏移时长(默认5分钟)
                    RequireExpirationTime = true                      //验证过期时间
                };
                opetion.Events = new JwtBearerEvents
                {
                    //未授权时触发
                    OnChallenge = context =>
                    {
                        context.Response.Headers.Add("Token-Error", context.ErrorDescription);
                        return(Task.CompletedTask);
                    },
                    //认证失败时触发
                    OnAuthenticationFailed = context =>
                    {
                        var token    = context.Request.Headers["Authorization"].ToString().Trim().Replace("Bearer ", "");
                        var jwtToken = (new JwtSecurityTokenHandler()).ReadJwtToken(token);

                        context.Response.ContentType = "text/plain charset/utf-8";
                        if (jwtToken.Issuer != Issuer)
                        {
                            context.Response.Headers.Add("Issuer", "issuer is wrong!");
                        }
                        if (jwtToken.Audiences.FirstOrDefault() != Audience)
                        {
                            context.Response.Headers.Add("Audience", "Audience is wrong!");
                        }
                        // 如果过期,添加到返回头信息中
                        if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                        {
                            context.Response.Headers.Add("Expired", "Token Expired!");
                        }
                        return(Task.CompletedTask);
                    }
                    //在Token验证通过后调用
                    //OnTokenValidated = context =>
                    //{
                    //    return Task.CompletedTask;
                    //}
                };
            });
            #endregion

            #region JWT授权
            // 角色与接口的权限要求参数
            var rolesList             = new List <string>(); //角色列表,登录时再赋值
            var roletype              = "Roles";
            var signingCredentials    = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
            var permissionRequirement = new PermissionRequirement(
                claimType: roletype,                      //自定义授权类型
                issuer: Issuer,                           //发行人
                audience: Audience,                       //听众
                signingCredentials: signingCredentials,   //签名凭据
                expiration: TimeSpan.FromSeconds(60 * 5), //接口的过期时间
                rolesList: rolesList);
            services.AddAuthorization(options =>
            {
                //角色授权,使用方式[Authorize(Policy="AdminPolicy")]
                //需要在生成token的claims中指定角色,如:new Claim(ClaimTypes.Role, "Admin")
                options.AddPolicy("AdminPolicy", o =>
                {
                    o.RequireRole("Admin").Build();
                });

                //自定义授权策略,使用方式 [Authorize(Policy="Permission")]
                options.AddPolicy("CustomPolicy", o =>
                {
                    o.Requirements.Add(permissionRequirement);
                });
            });

            services.AddScoped <IAuthorizationHandler, PermissionHandler>(); //注入权限处理
            services.AddSingleton(permissionRequirement);                    //单例注册
            services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>();
            //如果想要获取用户信息,还要注册一个用户服务,等权限验证通过之后,存储用户信息
            //services.AddScoped<IUser, AspNetUser>();
            #endregion

            #region 跨域

            //支持多个域名端口,注意端口号后不要带/斜杆:比如localhost:8000/,是错的
            //--http://127.0.0.1:1818 和 --http://localhost:1818 是不一样的,尽量写两个
            var origins = new List <string> {
                "http://127.0.0.1:8080", "http://localhost:8080", "http://192.168.0.7:8088"
            };
            services.AddCors(c =>
            {
                // 配置策略
                c.AddPolicy("CorsRequests", policy =>
                {
                    policy
                    .WithOrigins(origins.ToArray())
                    .AllowAnyHeader()   //允许任意头
                    .AllowAnyMethod();  //允许任意方法
                });
            });

            #endregion

            #region AutoMapper
            services.AddAutoMapper(typeof(AutoMapperConfig));
            AutoMapperConfig.AutoMapperRegister();
            #endregion

            //SqlSugar 注入
            //services.AddSqlSugar(new IocConfig()
            //{
            //    ConnectionString =Configuration["SqlServerString"],
            //    DbType = IocDbType.SqlServer,
            //    IsAutoCloseConnection = true    //自动关闭连接
            //});
        }