/// <summary>
        /// 根据用户角色进行权限认证
        /// </summary>
        /// <param name = "context" ></ param >
        /// < returns ></ returns >
        protected override async Task <bool> AuthorizeCoreAsync(HttpContext httpContext)
        {
            var endpointMetadata        = httpContext.Features.Get <IEndpointFeature>()?.Endpoint.Metadata;
            var allowAnonymousAttribute = endpointMetadata.GetMetadata <AllowAnonymousAttribute>();

            if (allowAnonymousAttribute != null)
            {
                return(true);
            }
            var jwtTokenService = httpContext.RequestServices.GetRequiredService <IJwtTokenService>();
            var jwtOptions      = jwtTokenService.GetOptions(httpContext.Request.GetString("appKey"));

            // 尝试刷新Token
            await TryRefreshTokenAsync(httpContext, jwtTokenService, jwtOptions);

            var authAttributeList = endpointMetadata.GetOrderedMetadata <AuthAttribute>();

            if (authAttributeList == null || !authAttributeList.Any())
            {
                return(true);
            }


            var validResult = new TokenValidResult();
            var token       = httpContext.GetAccessToken();

            if (!string.IsNullOrEmpty(token))
            {
                validResult.HasToken = true;
                validResult.Success  = false;
            }
            var(success, result) = await ValidTokenAsync(httpContext, jwtTokenService, jwtOptions, authAttributeList, validResult, token);

            if (success)
            {
                return(true);
            }

            SetHttpStatusCode(httpContext, HttpStatusCode.OK);
            await WriteResponseAsync(httpContext, result);

            return(false);
        }
Exemplo n.º 2
0
        public override async Task <(bool, JsonResult)> AuthorizeAsync(HttpContext httpContext, TokenValidResult validResult)
        {
            var url     = httpContext.Request.Path.Value.ToLower();
            var roleIds = httpContext.User.Claims.FirstOrDefault(c => c.Type.Equals(nameof(PermissionTokenEntity.RoleIds), StringComparison.InvariantCultureIgnoreCase))?.Value;
            var secutiryPermissionService = httpContext.RequestServices.GetService <IPermissionService>();

            if (secutiryPermissionService == null)
            {
                return(true, null);
            }

            if (roleIds.IsNullOrEmpty())
            {
                return(false, Provider.CreatePermissionNotAllowResponse(httpContext));
            }

            var userId = httpContext.User?.Claims.FirstOrDefault(c => c.Type.Equals(nameof(PermissionTokenEntity.UserId), StringComparison.InvariantCultureIgnoreCase))?.Value;

            if (userId.IsNullOrEmpty())
            {
                return(false, Provider.CreatePermissionNotAllowResponse(httpContext));
            }

            var store = httpContext.RequestServices.GetRequiredService <ICacheStore>();
            var entry = CacheEntryCollection.GetPermissionEntry(userId);
            IEnumerable <string> permissionList = await store.GetAsync <IEnumerable <string> >(entry);

            if (permissionList == null || !permissionList.Any())
            {
                permissionList = await secutiryPermissionService.GetPermissionCodeAsync(roleIds);

                if (permissionList != null && permissionList.Any())
                {
                    await store.SetAsync(entry, permissionList);
                }
            }

            var area       = httpContext.GetRouteValue("area")?.ToString();
            var controller = httpContext.GetRouteValue("controller")?.ToString();
            var action     = httpContext.GetRouteValue("action")?.ToString();
            var authCode   = AuthCode ??
                             (area != null ? $"{area}_{controller}.{action}" : $"{controller}.{action}");

            if (!permissionList.Any(d => string.Equals(d, authCode, System.StringComparison.InvariantCultureIgnoreCase)))
            {
                return(false, Provider.CreatePermissionNotAllowResponse(httpContext));
            }

            return(true, null);
        }
        private static async Task <(bool, JsonResult)> ValidTokenAsync(
            HttpContext httpContext,
            IJwtTokenService jwtTokenService,
            JwtOptions jwtOptions,
            IEnumerable <AuthAttribute> attributes,
            TokenValidResult validResult,
            string token)
        {
            ClaimsPrincipal principal = null;
            var             services  = httpContext.RequestServices;

            var logger = services.GetRequiredService <ILogger <RyeDefaultPolicyAuthorizationHandler> >();

            if (validResult.HasToken)
            {
                try
                {
                    principal = await jwtTokenService.ValidateTokenAsync(JwtTokenType.AccessToken, token, jwtOptions);

                    validResult.Success   = true;
                    validResult.HasExpire = false;
                    httpContext.User      = principal;
                }
                catch (SecurityTokenInvalidLifetimeException lifetimeEx)
                {
                    logger.LogError(lifetimeEx.ToString());
                    validResult.Success   = false;
                    validResult.HasExpire = true;
                }
                catch (Exception ex)
                {
                    logger.LogError(ex.ToString());
                    validResult.Success   = false;
                    validResult.HasExpire = false;
                }
            }

            var orderByAttributes = attributes.GroupBy(d => d.Priority).OrderBy(d => d.Key);

            foreach (var groupAttr in orderByAttributes)
            {
                var        success = true;
                JsonResult result  = null;
                foreach (var attr in groupAttr)
                {
                    (success, result) = await attr.AuthorizeAsync(httpContext, validResult);

                    if (!success)
                    {
                        return(success, result);
                    }
                }

                if (success) // 同级别的都验证成功的话,则直接返回结果
                {
                    return(success, result);
                }
            }

            return(true, null);
        }