/// <summary> /// 获取基于JWT的Token /// </summary> /// <param name="claims">需要在登陆的时候配置</param> /// <param name="permissionRequirement">在startup中定义的参数</param> /// <returns></returns> public static dynamic BuildJwtToken(Claim[] claims, PermissionRequirement permissionRequirement) { var now = DateTime.Now; // 实例化JwtSecurityToken var jwt = new JwtSecurityToken( issuer: permissionRequirement.Issuer, audience: permissionRequirement.Audience, claims: claims, notBefore: now, expires: now.Add(permissionRequirement.Expiration), signingCredentials: permissionRequirement.SigningCredentials ); // 生成 Token var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt); //打包返回前台 var responseJson = new { success = true, token = encodedJwt, expires_in = permissionRequirement.Expiration.TotalSeconds, token_type = "Bearer" }; return(responseJson); }
public void ConfigureServices(IServiceCollection services) { services.Configure <CookiePolicyOptions>(options => { options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); services.InjectionBusiness(configuration); // 配置MySQL的链接 services.InjectionBusinessServer(); //批量注入 服务类 services.AddMvc(a => a.EnableEndpointRouting = false ).SetCompatibilityVersion(CompatibilityVersion.Version_2_2); /*=============================*/ #region 这一种:[Authorize(AuthenticationSchemes = "myAuthentication")] // myAuthentication--自己自定义的认证方案 /*=================【授权】采用系统默认的就行====================*/ /*=================【自定义认证】====================*/ services.AddAuthenticationCore(options => options.AddScheme <MyHandler>("myAuthentication", "demo myAuthentication")); #endregion #region 第二种:[Authorize("Permission")] 或者 [Authorize(Roles = "admin1")] //TODO: [Authorize("Permission")] 这个策略中,包含的很多个 Role角色 都可以访问这个控制器, Permission 是一个完全自定义的认证逻辑 //TODO: [Authorize(Roles = "admin1") 。Jwt框架自带认证逻辑 #region 【授权】 //读取配置文件Permission IConfiguration audienceConfig = configuration.GetSection("Audience"); var symmetricKeyAsBase64 = audienceConfig["Secret"]; var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64); var signingKey = new SymmetricSecurityKey(keyByteArray); // 角色与接口的权限要求参数 PermissionRequirement permissionRequirement = new PermissionRequirement( "/api/denied", // 拒绝授权的跳转地址(目前无用) permissions: new List <PermissionItem>(), ClaimTypes.Role, //基于角色的授权 audienceConfig["Issuer"], //发行人 audienceConfig["Audience"], //听众 new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256), //签名凭据 expiration: TimeSpan.FromSeconds(60 * 2) //接口的过期时间 ); /*添加授权,配置授权的策略,控制器就这样写 [Authorize("Permission")] ,授权策略,他的角色在于 PermissionRequirement的 permissions#1*/ services.AddAuthorization(options => { options.AddPolicy("Permission", policy => policy.Requirements.Add(permissionRequirement)); //指定我们自定义的授权策略 }); // 注入 我们自定义的策略权限处理器,替换微软Core自带的 权限检查处理 services.AddSingleton <IAuthorizationHandler, PermissionHandler>(); services.AddSingleton(permissionRequirement); #endregion #region 【认证】Core 官方JWT认证 services.AddAuthentication(x => { x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(o => { o.TokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = signingKey, ValidateIssuer = true, ValidIssuer = audienceConfig["Issuer"], //发行人 ValidateAudience = true, ValidAudience = audienceConfig["Audience"], //订阅人 ValidateLifetime = true, ClockSkew = TimeSpan.Zero, RequireExpirationTime = true, }; o.Events = new JwtBearerEvents { // Jwt框架在认证的过程中,自带4个事件,用于扩展 OnAuthenticationFailed = context => { // 如果过期,则把<是否过期>添加到,返回头信息中 if (context.Exception.GetType() == typeof(SecurityTokenExpiredException)) { context.Response.Headers.Add("Token-Expired", "true"); } return(Task.CompletedTask); }, OnChallenge = context => { /*权限验证失败的事件*/ context.HandleResponse(); // 终止默认的返回类型和数据结果 context.Response.ContentType = "application/json"; context.Response.StatusCode = StatusCodes.Status200OK; //默认是401,改成200 var dde = Newtonsoft.Json.JsonConvert.SerializeObject(new { isok = false, Msg = "您没有权限!" }); context.Response.Body.Write(Encoding.UTF8.GetBytes(dde)); return(Task.FromResult(0)); }, OnMessageReceived = context => { /*收到消息*/ return(Task.CompletedTask); }, OnTokenValidated = context => { /*已经验证后*/ return(Task.CompletedTask); }, }; }); #endregion #endregion }