/// <summary> /// 添加Jwt认证授权参数 /// </summary> /// <param name="services"></param> /// <param name="configuration"></param> /// <param name="section"></param> /// <returns></returns> public static IServiceCollection AddTokenJwtAuthorize(this IServiceCollection services, IConfiguration configuration, string section = "JwtAuthorize") { var config = configuration.GetSection(section); var signingCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes(config["Secret"])), SecurityAlgorithms.HmacSha256); var permissionRequirement = new JwtAuthorizationRequirement(config["Issuer"], config["Audience"], signingCredentials); services.AddSingleton <ITokenBuilder, TokenBuilder>(); return(services.AddSingleton(permissionRequirement)); }
public LoginController( IEFCoreService efCoreService, JwtAuthorizationRequirement jwtRequirement, IUserInfoService userInfoService, IUserRoleService userRoleService, IRoleInfoService roleInfoService) { _EFCoreService = efCoreService; _jwtRequirement = jwtRequirement; _userInfoService = userInfoService; _userRoleService = userRoleService; _roleInfoService = roleInfoService; }
/// <summary> /// 添加Jwt认证 /// </summary> /// <param name="services"></param> /// <param name="configuration"></param> /// <param name="section"></param> /// <returns></returns> public static AuthenticationBuilder AddApiJwtAuthorize(this IServiceCollection services, IConfiguration configuration, string section = "JwtAuthorize") { var config = configuration.GetSection(section); var keyByteArray = Encoding.ASCII.GetBytes(config["Secret"]); var signingKey = new SymmetricSecurityKey(keyByteArray); var tokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = signingKey, ValidateIssuer = true, ValidIssuer = config["Issuer"], ValidateAudience = true, ValidAudience = config["Audience"], ValidateLifetime = true, ClockSkew = TimeSpan.Zero, RequireExpirationTime = bool.Parse(config["RequireExpirationTime"]) }; var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256); var permissionRequirement = new JwtAuthorizationRequirement(config["Issuer"], config["Audience"], signingCredentials); services.AddSingleton <IClaimsParser, ClaimsParser>(); services.AddSingleton <IPermissionAuthoriser, EmptyAuthoriser>(); services.AddSingleton <IPermissionRepository, EmptyPermissionRepository>(); services.AddSingleton <IAuthorizationHandler, PermissionHandler>(); services.AddSingleton(permissionRequirement); return(services.AddAuthorization(options => { options.AddPolicy(config["PolicyName"], policy => policy.Requirements.Add(permissionRequirement)); }) .AddAuthentication(options => { options.DefaultScheme = config["DefaultScheme"]; }) .AddJwtBearer(config["DefaultScheme"], o => { o.RequireHttpsMetadata = bool.Parse(config["IsHttps"]); o.TokenValidationParameters = tokenValidationParameters; })); }
// This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { #region 初始化配置 //初始化配置 services.Configure <LLSetting>(Configuration.GetSection("LLSetting")); services.Configure <JWTSetting>(Configuration.GetSection("JWTSetting")); services.Configure <ImagePathSetting>(Configuration.GetSection("ImagePathSetting")); #endregion #region ConfigureServices中读取配置 string Issuer = Configuration.GetSection("JWTSetting").GetSection("Issuer").Value; string CookieScheme = Configuration.GetSection("CookieSetting").GetSection("CookieScheme").Value; string Audience = Configuration.GetSection("JWTSetting:Audience").Value; string SecretKey = Configuration.GetSection("JWTSetting:SecretKey").Value; #endregion #region Authentication cookie,JwtBearer 认证配置 var jwtAuthorizationRequirement = new JwtAuthorizationRequirement(); //添加认证Cookie信息 services.AddAuthentication(CookieScheme) // Sets the default to cookies .AddCookie(CookieScheme, options => { options.AccessDeniedPath = "/Account/Denied"; //禁止访问路径:当用户试图访问资源时,但未通过该资源的任何授权策略,请求将被重定向到这个相对路径(没有权限跳转)。 options.LoginPath = System.Web.HttpUtility.UrlEncode("/Account/Index"); // 登录路径:这是当用户试图访问资源但未经过身份验证时,程序将会将请求重定向到这个相对路径。 //options.SlidingExpiration = true; //Cookie可以分为永久性的和临时性的。 临时性的是指只在当前浏览器进程里有效,浏览器一旦关闭就失效(被浏览器删除)。 永久性的是指Cookie指定了一个过期时间,在这个时间到达之前,此cookie一直有效(浏览器一直记录着此cookie的存在)。 slidingExpriation的作用是,指示浏览器把cookie作为永久性cookie存储,但是会自动更改过期时间,以使用户不会在登录后并一直活动,但是一段时间后却自动注销。也就是说,你10点登录了,服务器端设置的TimeOut为30分钟,如果slidingExpriation为false,那么10:30以后,你就必须重新登录。如果为true的话,你10:16分时打开了一个新页面,服务器就会通知浏览器,把过期时间修改为10:46。 更详细的说明还是参考MSDN的文档。 options.Events = new CookieAuthenticationEvents() { //覆写跳转到登陆页事件 OnRedirectToLogin = context => { /* * 由于 LoginPath 前台页面url 会被编码 * ps:覆写事件 对url进行转码 * */ context.Response.Redirect(System.Uri.UnescapeDataString(context.RedirectUri)); return(System.Threading.Tasks.Task.FromResult(0)); } }; }); #region jwt #region Jwt默认 //.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, jwtoptions => //{ // jwtoptions.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters // { // //Token颁发机构 // ValidIssuer = "https://localhost:44303/", // //颁发给谁 // ValidAudience = "https://localhost:44303/", // //这里的key要进行加密,需要引用Microsoft.IdentityModel.Tokens // IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("LL_2AWopCMMgEIWt6KkzxEJD0EA4xreXLINaQIDAQABAoGAcUQIoKWyldZa8xnPDJTMKIV8GpeuzebKWvwp5dIu+miTdzmZX4weeHADRNb")), // //验证token 有效期 // ValidateLifetime = true, // //ValidateIssuer = true, // //ValidateAudience = true, // //ValidateIssuerSigningKey=true // ///允许的服务器时间偏移量 // //ClockSkew = TimeSpan.Zero // }; //}); #endregion #region Jwt自定义策略 /* * 1.添加授权自定义策略 policy * 2.设置认证方式(cookie、bearer、openid) * 3.添加JWT认证机制 */ //1.添加授权自定义策略 services.AddAuthorization(option => { option.AddPolicy("LL_Jwt", policy => { //参数约束 policy.AddRequirements(jwtAuthorizationRequirement); }); //2.设置认证方式(cookie、bearer、openid) }).AddAuthentication(option => { option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(o => { o.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters { //Token颁发机构 ValidIssuer = Issuer, //颁发给谁 ValidAudience = Audience, //这里的key要进行加密,需要引用Microsoft.IdentityModel.Tokens IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SecretKey)), //验证token 有效期 ValidateLifetime = true, //ValidateIssuer = true, //ValidateAudience = true, ValidateIssuerSigningKey = true ///允许的服务器时间偏移量 //ClockSkew = TimeSpan.Zero }; }); #endregion #endregion #endregion #region UEditor文本编辑器 services.AddUEditorService(configFileRelativePath: "ueditor_config.json", isCacheConfig: false, basePath: ""); #endregion #region 依赖注入 服务 //注册EF上下文 services.AddDbContext <LLDbContext>(options => { options.UseSqlServer( //数据是sql server 2008 开启 UseRowNumberForPaging Configuration.GetConnectionString("LLDbContext"), b => b.UseRowNumberForPaging()); }); // Transient: 每一次GetService都会创建一个新的实例 // Scoped: 在同一个Scope内只初始化一个实例 ,可以理解为( 每一个request级别只创建一个实例,同一个http request会在一个 scope内) // Singleton :整个应用程序生命周期以内只创建一个实例 services.AddTransient <IUsersService, UsersService>(); //jwt 自定义验证AuthorizationHandler时间 services.AddSingleton <IAuthorizationHandler, JwtAuthorizationHandler>(); #endregion #region 初始化数据 //获取注册的服务 ServiceProvider serviceProvider = services.BuildServiceProvider(); LLDbContext dbcontext = serviceProvider.GetService <LLDbContext>(); DataInitialize.DataInit(dbcontext); #endregion services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); #region 数据保护组件 //.NETCore 数据保护组件 services.AddDataProtection(); #endregion }
public LoginController(JwtAuthorizationRequirement jwtAuthorizationRequirement, ILogger <LoginController> logger) { _logger = logger; _jwtAuthorizationRequirement = jwtAuthorizationRequirement; }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { //注册控制器 并追加控制的全局过滤 services.AddControllers(o => { o.Filters.Add(typeof(GlobalExceptionFilter)); }); var basePath = Microsoft.DotNet.PlatformAbstractions.ApplicationEnvironment.ApplicationBasePath; //注册EF 上下文 // services.AddDbContext<MyContext>( // o => o.UseSqlite(@"Data Source=D:\Code\Project\XiaoQi.Study\XiaoQi.Study.API\DB\userinfo.db") //); services.AddDbContext <MyContext>( o => o.UseSqlite(@"Data Source=" + basePath + "userinfo.db") ); //Swagger 相关注册 services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "XiaoQi API", Version = "v1" }); //为Swagger json 和 UI 增加注释信息 var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); c.IncludeXmlComments(xmlPath); }); //注册封装好的EFCoreService services.AddScoped <IEFCoreService, EFCoreService>(); #region 注册所有得数据服务 //services.AddTransient<IMenuButtonRepository, MenuButtonRepository>(); //services.AddTransient<IMenuInfoRepository, MenuInfoRepository>(); //services.AddTransient<IRoleInfoRepository, RoleInfoRepository>(); //services.AddTransient<IRoleMenuRepository, RoleMenuRepository>(); //services.AddTransient<IUserInfoRepository, UserInfoRepository>(); //services.AddTransient<IUserRoleRepository, UserRoleRepository>(); //services.AddTransient<IMenuButtonService, MenuButtonService>(); //services.AddTransient<IMenuInfoService, MenuInfoService>(); //services.AddTransient<IRoleInfoService, RoleInfoService>(); //services.AddTransient<IRoleMenuService, RoleMenuService>(); //services.AddTransient<IUserInfoService, UserInfoService>(); //services.AddTransient<IUserRoleService, UserRoleService>(); #endregion //注册此接口,给JwtAuthorizationHandler.cs 用 services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>(); #region 权限验证相关 // 授权验证的资源 var jwtKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("xiaoqiyaozouxiaoqiyaozouxiaoqiyaozou")); //加密验证的key var jwtCreds = new SigningCredentials(jwtKey, SecurityAlgorithms.HmacSha256); //根据key' 生成的标识 var jwtUserRoleInofs = new List <JwtUserRoleInfo>(); //用户角色和用户拥有的api 集合 ,该角色只能访问其拥有的api var jwtRequirement = new JwtAuthorizationRequirement( jwtUserRoleInofs, "", ClaimTypes.Role, expiration: TimeSpan.FromSeconds(60 * 60), "", "Issuer", "Audience", jwtCreds ); services.AddSingleton(jwtRequirement);//将该资源注册,可以在验证处理器种设置其值 //注册策略授权 services.AddAuthorization(o => { o.AddPolicy("MyPolicy", policy => policy.Requirements.Add(jwtRequirement)); }); //验证参数设置 var tokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = jwtKey, ValidateIssuer = true, ValidIssuer = "Issuer", //发行人 ValidateAudience = true, ValidAudience = "Audience", //订阅人 ValidateLifetime = true, ClockSkew = TimeSpan.FromSeconds(30), RequireExpirationTime = true, }; // 开启Bearer认证 services.AddAuthentication(o => { o.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; o.DefaultChallengeScheme = nameof(ApiResponseHandler); o.DefaultForbidScheme = nameof(ApiResponseHandler); }) // 添加JwtBearer服务 .AddJwtBearer(o => { o.TokenValidationParameters = tokenValidationParameters; o.Events = new JwtBearerEvents { OnAuthenticationFailed = context => { // 如果过期,则把<是否过期>添加到,返回头信息中 if (context.Exception.GetType() == typeof(SecurityTokenExpiredException)) { context.Response.Headers.Add("Token-Expired", "true"); } return(Task.CompletedTask); } }; }) .AddScheme <AuthenticationSchemeOptions, ApiResponseHandler>(nameof(ApiResponseHandler), o => { }); // 注入权限处理器 services.AddScoped <IAuthorizationHandler, JwtAuthorizationHandler>(); #endregion //注册跨域 services.AddCors(options => { string[] arr1 = { "http://192.168.1.3:9999", "http://localhost:8080", "http://152.136.33.250:6004" }; string[] arr = Configuration["OriginSetting"].Split(','); //{ "http://192.168.1.3:9999", "http://localhost:8080", "http://152.136.33.250:6004" }; options.AddPolicy("XiaoQiAllowOrigins", builder => { builder.WithOrigins(arr) .AllowAnyHeader() .AllowAnyMethod(); }); }); }