123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- using IdentityModel;
- using Microsoft.AspNetCore.Authentication.JwtBearer;
- using Microsoft.AspNetCore.Authorization;
- using Microsoft.Extensions.Configuration;
- using Microsoft.Extensions.DependencyInjection;
- using Microsoft.IdentityModel.Tokens;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- using TEAMModelOS.SDK.Context.Configuration;
- using TEAMModelOS.SDK.Helper.Security.RSACrypt;
- namespace HiTeachCE.Extension
- {
- public static class JwtAuth
- {
- public static void Auth(this IServiceCollection services, IConfigurationSection configuration)
- {
- services.Configure<JwtSetting>(configuration);
- string path = BaseConfigModel.ContentRootPath;
- SecurityKey creds = RsaHelper.GenerateValidationKey(path + "/public.pem");
- // 令牌验证参数
- var tokenValidationParameters = new TokenValidationParameters
- {
- //NameClaimType = JwtClaimTypes.Name,
- //RoleClaimType = JwtClaimTypes.Role,
- ValidateIssuerSigningKey = true,
- IssuerSigningKey = creds,
- ValidateIssuer = true,
- ValidIssuer = configuration["Issuer"],//发行人
- ValidateAudience = true,
- ValidAudience = configuration["Audience"],//订阅人
- ValidateLifetime = true,// 是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比
- //允许的服务器时间偏移量
- ClockSkew = TimeSpan.Zero,
- //是否要求Token的Claims中必须包含Expires
- RequireExpirationTime = true,
- };
- //https://github.com/HeartofTheForce/Heart.Auth/blob/22df97c854dc48ed9fbadf0bc185a6489aa25354/Heart.Auth.Api/Setup/Extensions/SetupAuth.cs
- //RSA public private
- services.AddAuthentication
- (x =>
- {
- x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
- x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
- x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
- })
- .AddJwtBearer(o =>
- {
- ///https://blog.csdn.net/sinat_14899485/article/details/88591848 jwt 黑名单
- //o.SecurityTokenValidators.Clear();
- o.SecurityTokenValidators.Add(new BlackListJwtSecurityTokenHandler()); /// 自定义黑名单拦截
- 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;
- },
- //Url中添加access_token=[token],直接在浏览器中访问
- OnMessageReceived = context => {
- context.Token = context.Request.Query["access_token"];
- return Task.CompletedTask;
- },
- //URL未授权调用
- OnChallenge = context => {
- return Task.CompletedTask;
- },
- //在Token验证通过后调用
- OnTokenValidated = context => {
- //编写业务
- return Task.CompletedTask;
- },
- };
- });
- if (services == null) throw new ArgumentNullException(nameof(services));
- // 1【授权】、这个和上边的异曲同工,好处就是不用在controller中,写多个 roles 。
- // 然后这么写 [Authorize(Policy = "Admin")]
- services.AddAuthorization(options =>
- {
- options.AddPolicy("root", policy => policy.RequireRole("root").Build());
- options.AddPolicy("admin", policy => policy.RequireRole("admin").Build());
- options.AddPolicy("lecturer", policy => policy.RequireRole("lecturer").Build());
- options.AddPolicy("learner", policy => policy.RequireRole("learner").Build());
- options.AddPolicy("rootOrlearner", policy => policy.RequireRole("root","learner").Build());
- options.AddPolicy("all", policy => policy.RequireRole("root","admin" ,"learner").Build());
- });
- }
- }
- }
|