我正在尝试在各个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();
}
使用自定义授权管理器
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资源。
我是新手,所以我对所有概念都没有透彻的理解,所以请告诉我是否遗漏了什么。
答案 0 :(得分:0)
根据ClaimsPrincipalPermission.Demand
的文件“如果当前委托人未获得指定行动的授权 在指定的资源上,抛出SecurityException;除此以外, 执行进行。“
然后解决方案是在解决方案中创建一个异常处理程序并返回UnAuthorized Http响应。 (我真的认为默认情况下ASP.Net会这样做,但我从来没有检查/反映过那个:)