ASP.NET Core 6 Web API:如何判断指定ActionDescriptor的操作是否需认证?
判断ASP.NET Core中ActionDescriptor对应的操作是否需要身份认证
问题描述
给定一个ActionDescriptor(例如对应GET /api/Item/{id}接口的实例),如何判断该操作是否需要身份认证?仅检查操作方法及其所属类的AuthorizeAttribute或AllowAnonymousAttribute过滤器并不靠谱,因为这种方式无法考虑AuthorizationOptions中的策略(如FallbackPolicy、DefaultPolicy以及通过AddPolicy()添加的策略)。曾查看以下接口是否存在接收ActionDescriptor的方法,但遗憾的是都没有:
IAuthorizationPolicyProviderIAuthorizationServiceIAuthorizationHandlerIAuthorizationHandlerContextFactoryIAuthorizationHandlerProvider
补充:WebForms中有类似UrlAuthorizationModule.CheckUrlAccessForPrincipal()的方法,想知道ASP.NET Core中是否有类似功能。
解决方案
核心思路
要完整判断Action是否需要认证,必须结合Action本身的授权元数据和全局配置的授权策略(默认策略、回退策略),通过AuthorizationPolicyProvider来组合最终生效的策略,再判断是否存在需要验证的规则。
具体实现代码
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvcvc.Abstractions; public class ActionAuthorizationChecker { private readonly IAuthorizationPolicyProvider _policyProvider; public ActionAuthorizationChecker(IAuthorizationPolicyProvider policyProvider) { _policyProvider = policyProvider; } public async Task<bool> IsActionRequiresAuthentication(ActionDescriptor actionDescriptor) { // 优先检查AllowAnonymous,存在则直接无需认证 if (actionDescriptor.EndpointMetadata.Any(m => m is AllowAnonymousAttribute)) { return false; } // 获取Action上的所有Authorize特性 var authorizeAttributes = actionDescriptor.EndpointMetadata .OfType<AuthorizeAttribute>() .ToList(); // 构建Action级别的授权策略 AuthorizationPolicy? actionPolicy = null; if (authorizeAttributes.Any()) { // 如果指定了策略名称,优先获取对应策略 if (!string.IsNullOrEmpty(authorizeAttributes.First().Policy)) { actionPolicy = await _policyProvider.GetPolicyAsync(authorizeAttributes.First().Policy); } // 否则组合多个Authorize特性的规则 else { actionPolicy = AuthorizationPolicy.Combine(_policyProvider, authorizeAttributes); } } // 获取全局默认策略和回退策略 var defaultPolicy = await _policyProvider.GetDefaultPolicyAsync(); var fallbackPolicy = await _policyProvider.GetFallbackPolicyAsync(); // 按优先级组合策略:回退策略 > 默认策略 > Action级策略 var finalPolicy = AuthorizationPolicy.Combine(fallbackPolicy, AuthorizationPolicy.Combine(defaultPolicy, actionPolicy)); // 最终策略不为空,说明需要身份认证 return finalPolicy != null; } }
类似WebForms的权限检查实现
ASP.NET Core中没有直接对应UrlAuthorizationModule.CheckUrlAccessForPrincipal()的方法,但可以通过IAuthorizationService实现等效的权限验证逻辑,传入用户主体和ActionDescriptor作为资源:
public async Task<bool> CheckActionAccessForPrincipal(ActionDescriptor actionDescriptor, ClaimsPrincipal user, IAuthorizationService authorizationService) { // 授权服务会自动使用Action对应的所有策略(包括全局策略)进行验证 var authResult = await authorizationService.AuthorizeAsync(user, actionDescriptor, null); return authResult.Succeeded; }
内容的提问来源于stack exchange,提问作者Oliver
相关产品推荐
相关产品推荐

