ABP点滴:API无权访问资源时,返回 PolicyName 信息
2023-06-18 19:52 无常 阅读(220) 评论(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;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库