ABP点滴:API无权访问资源时,返回 PolicyName 信息
2023-06-18 19:52 无常 阅读(156) 评论(0) 编辑 收藏 举报ABP无权访问API时,返回的是403 Forbidden 和重定向 Localtion ,但不知道具体是哪个Policy受阻。
整改思路:
- 重写
MethodInvocationAuthorizationService
, 抛出AbpAuthorizationException
异常时附带 PolicyName - 重写
DefaultAbpAuthorizationExceptionHandler
,在http响应头中增加上无权限的 PolicyName。 - 前端判断返回403再从headers中获取
效果如:
相关源码:
[ExposeServices(typeof(IAbpAuthorizationExceptionHandler))]
[Dependency(ReplaceServices = true)]
public class Ch2AuthorizationExceptionHandler : DefaultAbpAuthorizationExceptionHandler
{
public Ch2AuthorizationExceptionHandler()
{
}
public override Task HandleAsync(AbpAuthorizationException exception, HttpContext httpContext)
{
if (exception.Data.Contains("PolicyName"))
{
var policyName = (string)exception.Data["PolicyName"]!;
httpContext.Response.Headers.Add("X-Policy-Name", new Microsoft.Extensions.Primitives.StringValues(policyName));
}
return base.HandleAsync(exception, httpContext);
}
}
[ExposeServices(typeof(IMethodInvocationAuthorizationService))]
[Volo.Abp.DependencyInjection.Dependency(ReplaceServices = true)]
public class Ch2MethodInvocationAuthorizationService : IMethodInvocationAuthorizationService, ITransientDependency
{
private readonly IAbpAuthorizationPolicyProvider _abpAuthorizationPolicyProvider;
private readonly IAbpAuthorizationService _abpAuthorizationService;
public Ch2MethodInvocationAuthorizationService(
IAbpAuthorizationPolicyProvider abpAuthorizationPolicyProvider,
IAbpAuthorizationService abpAuthorizationService)
{
_abpAuthorizationPolicyProvider = abpAuthorizationPolicyProvider;
_abpAuthorizationService = abpAuthorizationService;
}
public async Task CheckAsync(MethodInvocationAuthorizationContext context)
{
if (AllowAnonymous(context))
{
return;
}
var authorizationPolicy = await AuthorizationPolicy.CombineAsync(
_abpAuthorizationPolicyProvider,
GetAuthorizationDataAttributes(context.Method)
);
if (authorizationPolicy == null)
{
return;
}
//改动这里
//await _abpAuthorizationService.CheckAsync(authorizationPolicy);
if (!await _abpAuthorizationService.IsGrantedAsync(authorizationPolicy))
{
var policys = authorizationPolicy.Requirements.Cast<PermissionRequirement>()
.Select(o => o.PermissionName).JoinAsString(",");
throw new AbpAuthorizationException(code: AbpAuthorizationErrorCodes.GivenPolicyHasNotGranted)
.WithData("PolicyName", policys);
}
}
protected virtual bool AllowAnonymous(MethodInvocationAuthorizationContext context)
{
return context.Method.GetCustomAttributes(true).OfType<IAllowAnonymous>().Any();
}
protected virtual IEnumerable<IAuthorizeData> GetAuthorizationDataAttributes(MethodInfo methodInfo)
{
var attributes = methodInfo
.GetCustomAttributes(true)
.OfType<IAuthorizeData>();
if (methodInfo.IsPublic && methodInfo.DeclaringType != null)
{
attributes = attributes
.Union(
methodInfo.DeclaringType
.GetCustomAttributes(true)
.OfType<IAuthorizeData>()
);
}
return attributes;
}
}