ClaimsPrincipalPermission和ClaimsAuthorization属性使用不同的信息,这是最好的

本文关键字:信息 ClaimsAuthorization 属性 ClaimsPrincipalPermission | 更新日期: 2023-09-27 17:50:33

我正试图在单个webapi上实现索赔基础授权…然而,我不希望用户声称与webapi紧密耦合。使用ClaimsPrincipalPermissions,我得到了想要的解耦,因为我可以将用户分配给数据库中的资源。例如

Webapi方法
    [ClaimsPrincipalPermission(SecurityAction.Demand, Operation = "Manage", Resource = "Roles")]
    public async Task<IHttpActionResult> GetRole(string Id)
    {
        var role = await AppRoleManager.FindByIdAsync(Id);
        if (role != null)
        {
            return Ok(ModelFactory.Create(role));
        }
        return NotFound();
    }

使用自定义AuthorizationManager

public class AuthorizationManager : ClaimsAuthorizationManager
{
    public override bool CheckAccess(AuthorizationContext context)
    {
        //return base.CheckAccess(context);
        string resource = context.Resource.First().Value;
        string action = context.Action.First().Value;
        if (action == "Manage" && resource == "Roles")
        {
            // check for roles
            //context.Principal.IsInRole("Admin");
            bool hasRolesManagement = context.Principal.HasClaim("ManageRoles", "True");
            return hasRolesManagement;
        }
        return false;
    }
}

我可以对特定的登录用户进行适当的检查,检查他们对所访问资源的声明。但是,我不能以这种方式将适当的未经授权的响应踢回给用户。我发现的另一个例子是下面的webapi如下所示

    [ClaimsAuthorization(ClaimType="ManageRoles", ClaimValue="True")]
    [Route("")]
    public IHttpActionResult Get()
    {
        return Ok();
    }

然后使用自定义声明授权属性

public class ClaimsAuthorizationAttribute : AuthorizationFilterAttribute
{
    public string ClaimType { get; set; }
    public string ClaimValue { get; set; }
    public override Task OnAuthorizationAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken)
    {
        var principal = actionContext.RequestContext.Principal as ClaimsPrincipal;
        if (!principal.Identity.IsAuthenticated)
        {
            actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
            return Task.FromResult<object>(null);
        }
        if (!(principal.HasClaim(x => x.Type == ClaimType && x.Value == ClaimValue)))
        {
            actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
            return Task.FromResult<object>(null);
        }
        //User is Authorized, complete execution
        return Task.FromResult<object>(null);
    }
}

这使我能够访问actionContext以发送回适当的statusCoded响应。

对于第二种方法的重要警告是,对于我必须重新编译代码的新声明,要为api方法引入可访问性。

所以我的问题是我如何才能获得第一种方法的灵活性,其中每个api被指定为资源,并且在数据库中将声明分配给资源,但仍然获得第二种方法的灵活性,其中我可以访问操作上下文并能够返回正确的状态编码响应?我们不想为了允许其他角色/声明访问webapi资源而重新编译代码。

我是claim的新手,所以我对所有的概念还没有透彻的理解,如果我遗漏了什么,请告诉我。

ClaimsPrincipalPermission和ClaimsAuthorization属性使用不同的信息,这是最好的

根据ClaimsPrincipalPermission的文档。需求

"如果当前主体未被授权执行指定操作在指定的资源上,抛出SecurityException;否则,执行收益。"

解决方案是在解决方案中创建一个异常处理程序,并返回一个未经授权的Http响应。(我真的认为ASP。Net默认是这样做的,但我从来没有检查过/反映过:)