|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
-
- //
-
-
-
-
-
-
-
-
- using MoYu.Authorization;
- using MoYu.DataEncryption;
- using MoYu.Logging.Extensions;
- using System.Security.Claims;
-
- namespace SafeCampus.Web.Core;
-
- public class JwtHandler : AppAuthorizeHandler
- {
- /// <summary>
- /// 重写 Handler 添加自动刷新
- /// </summary>
- /// <param name="context"></param>
- /// <param name="httpContext"></param>
- /// <returns></returns>
- public override async Task HandleAsync(AuthorizationHandlerContext context, DefaultHttpContext httpContext)
- {
- var expire = App.GetConfig<int>("JWTSettings:ExpiredTime");//获取过期时间(分钟)
- var currentHttpContext = context.GetCurrentHttpContext();
- //自动刷新Token
- if (JWTEncryption.AutoRefreshToken(context, currentHttpContext, expire, expire * 2))
- {
- //判断token是否有效
- if (CheckTokenFromRedis(currentHttpContext, expire))
- {
- await AuthorizeHandleAsync(context);
- }
- else
- {
- currentHttpContext.Response.StatusCode = 401;//返回401给授权筛选器用
- }
- }
- else
- {
- context.Fail();// 授权失败
- if (currentHttpContext == null)
- return;
- currentHttpContext.SignoutToSwagger();
- }
- }
-
- /// <summary>
- /// 检查token有效性
- /// </summary>
- /// <param name="context">DefaultHttpContext</param>
- /// <param name="expire">token有效期/分钟</param>
- /// <returns></returns>
- private bool CheckTokenFromRedis(DefaultHttpContext context, int expire)
- {
- var token = JWTEncryption.GetJwtBearerToken(context);//获取当前token
- var userId = App.User?.FindFirstValue(ClaimConst.USER_ID);//获取用户ID
- var simpleCacheService = App.GetService<ISimpleCacheService>();//获取redis实例
- var tokenInfos = simpleCacheService.HashGetOne<List<TokenInfo>>(CacheConst.CACHE_USER_TOKEN, userId);//获取token信息
- if (tokenInfos == null)//如果还是空
- {
- return false;
- }
-
- var tokenInfo = tokenInfos.Where(it => it.Token == token).FirstOrDefault();//获取redis中token值是当前token的对象
- if (tokenInfo != null)
- {
- // 自动刷新token返回新的Token
- var accessToken = context.Response.Headers["access-token"].ToString();
- if (!string.IsNullOrEmpty(accessToken))//如果有新的刷新token
- {
- "返回新的刷新token".LogDebug<JwtHandler>();
- tokenInfo.Token = accessToken;//新的token
- tokenInfo.TokenTimeout = DateTime.Now.AddMinutes(expire);//新的过期时间
- simpleCacheService.HashAdd(CacheConst.CACHE_USER_TOKEN, userId, tokenInfos);//更新token信息到redis
- }
- }
- else
- {
- return false;
- }
-
- return true;
- }
-
- /// <summary>
- /// 授权判断逻辑,授权通过返回 true,否则返回 false
- /// </summary>
- /// <param name="context"></param>
- /// <param name="httpContext"></param>
- /// <returns></returns>
- public override async Task<bool> PipelineAsync(AuthorizationHandlerContext context, DefaultHttpContext httpContext)
- {
- // 这里写您的授权判断逻辑,授权通过返回 true,否则返回 false
-
- // 此处已经自动验证 Jwt Token的有效性了,无需手动验证
- return await CheckAuthorizationAsync(httpContext);
- }
-
- /// <summary>
- /// 检查权限
- /// </summary>
- /// <param name="httpContext"></param>
- /// <returns></returns>
- private static async Task<bool> CheckAuthorizationAsync(DefaultHttpContext httpContext)
- {
- //超级管理员都能访问
- if (UserManager.SuperAdmin) return true;
- // 获取超级管理员特性
- var isSuperAdmin = httpContext.GetMetadata<SuperAdminAttribute>();
- if (isSuperAdmin != null)//如果是超级管理员才能访问的接口
- {
- //获取忽略超级管理员特性
- var ignoreSuperAdmin = httpContext.GetMetadata<IgnoreSuperAdminAttribute>();
- if (ignoreSuperAdmin == null && !UserManager.SuperAdmin)//如果只能超级管理员访问并且用户不是超级管理员
- return false;//直接没权限
- }
-
- //获取角色授权特性
- var isRolePermission = httpContext.GetMetadata<RolePermissionAttribute>();
- if (isRolePermission != null)
- {
- //获取忽略角色授权特性
- var ignoreRolePermission = httpContext.GetMetadata<IgnoreRolePermissionAttribute>();
- if (ignoreRolePermission == null)
- {
- // 路由名称
- var routeName = httpContext.Request.Path.Value;
- //获取用户信息
- var userInfo = await App.GetService<ISysUserService>().GetUserById(UserManager.UserId);
- if (!userInfo.PermissionCodeList.Contains(routeName))//如果当前路由信息不包含在角色授权路由列表中则认证失败
- return false;
- }
- }
-
- return true;
- }
- }
|