c# - 自定义授权属性 - ASP .NET Core 2.2
问题描述
我想创建一个自定义 Authorize 属性,以便能够在失败时发送个性化响应。有很多例子,但我找不到我要找的东西。注册保单时,我添加了“索赔”。是否可以在自定义属性中访问已注册的声明而无需通过参数传递声明?或者是否有可能知道索赔检查是否发生,如果没有,返回个性化回复?谢谢!
public static void AddCustomAuthorization(this IServiceCollection serviceCollection)
{
serviceCollection.AddAuthorization(x =>
{
x.AddPolicy(UserPolicy.Read,
currentPolicy => currentPolicy.RequireClaim(UserClaims.Read));
});
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public class CustomAuthorizeAttribute : AuthorizeAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationFilterContext authorizationFilterContext)
{
if (authorizationFilterContext.HttpContext.User.Identity.IsAuthenticated)
{
if (!authorizationFilterContext.HttpContext.User.HasClaim(x => x.Value == "CLAIM_NAME")) // ACCESS TO REGISTER CLAIM => currentPolicy => currentPolicy.RequireClaim(UserClaims.Read)
{
authorizationFilterContext.Result = new ObjectResult(new ApiResponse(HttpStatusCode.Unauthorized));
}
}
}
}
[HttpGet]
[CustomAuthorizeAttribute(Policy = UserPolicy.Read)]
public async Task<IEnumerable<UserDTO>> Get()
{
return ...
}
解决方案
您可以使用IAuthorizationPolicyProvider
获取策略,然后使用ClaimsAuthorizationRequirement.ClaimType
获取声明名称。而且由于它具有异步 API,因此最好使用IAsyncAuthorizationFilter
而不是IAuthorizationFilter
. 尝试这个:
public class CustomAuthorizeAttribute : AuthorizeAttribute, IAsyncAuthorizationFilter
{
public async Task OnAuthorizationAsync(AuthorizationFilterContext authorizationFilterContext)
{
var policyProvider = authorizationFilterContext.HttpContext
.RequestServices.GetService<IAuthorizationPolicyProvider>();
var policy = await policyProvider.GetPolicyAsync(UserPolicy.Read);
var requirement = (ClaimsAuthorizationRequirement)policy.Requirements
.First(r => r.GetType() == typeof(ClaimsAuthorizationRequirement));
if (authorizationFilterContext.HttpContext.User.Identity.IsAuthenticated)
{
if (!authorizationFilterContext.HttpContext
.User.HasClaim(x => x.Value == requirement.ClaimType))
{
authorizationFilterContext.Result =
new ObjectResult(new ApiResponse(HttpStatusCode.Unauthorized));
}
}
}
}
推荐阅读
- amazon-web-services - AWS ASG 生命周期通知目标
- c# - 如何路由 401 和 403 错误?
- c++ - 您将如何嵌套结构?
- xml - XSLT - 未设置根元素
- rest - 为什么使用 Google Cloud Drive Rest API file.list 无法获取所有文件?
- python - 如何在 py 编辑器中添加多个 @app.route?
- python-3.x - Python3:在空的熊猫数据框中添加多列行
- php - 有时 ftp_connect() 不能在 php 中工作,其余时间它工作得很好
- javascript - 如何在另一个页面中使用表单选择值
- dvd - 如何将 DVD 复制到本地系统?