C# ClaimsPrincipalPermission与ClaimsAuthorization属性使用不同的信息,最好使用哪种信息
我正在尝试在单个webapi上实现基于声明的授权。。。但是,我不希望用户声称与webapi紧密耦合。使用ClaimsPrincipalPermissions,我可以获得所需的解耦,因为我可以将用户分配给数据库中的资源。比如说 Webapi方法C# ClaimsPrincipalPermission与ClaimsAuthorization属性使用不同的信息,最好使用哪种信息,c#,asp.net-web-api,claims-based-identity,C#,Asp.net Web Api,Claims Based Identity,我正在尝试在单个webapi上实现基于声明的授权。。。但是,我不希望用户声称与webapi紧密耦合。使用ClaimsPrincipalPermissions,我可以获得所需的解耦,因为我可以将用户分配给数据库中的资源。比如说 Webapi方法 [ClaimsPrincipalPermission(SecurityAction.Demand, Operation = "Manage", Resource = "Roles")] public async Task<IHttpA
[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();
}
我可以对某个特定的登录用户进行适当的检查,根据他们所访问的资源检查他们的声明。但是,我不能以这种方式将适当的未经授权的响应回退给用户。下面是我发现的另一个示例,其中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);
}
}
公共类ClaimsAuthorizationAttribute:AuthorizationFilterAttribute
{
公共字符串ClaimType{get;set;}
公共字符串ClaimValue{get;set;}
AuthorizationAsync上的公共重写任务(HttpActionContext actionContext,System.Threading.CancellationToken CancellationToken)
{
var principal=actionContext.RequestContext.principal作为ClaimsPrincipal;
如果(!principal.Identity.IsAuthenticated)
{
actionContext.Response=actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
返回Task.FromResult(空);
}
if(!(principal.HasClaim(x=>x.Type==ClaimType&&x.Value==ClaimValue)))
{
actionContext.Response=actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
返回Task.FromResult(空);
}
//用户被授权,完成执行
返回Task.FromResult(空);
}
}
这使我能够访问actionContext,以发回正确的状态编码响应
第二种方法的一个重要警告是为api方法引入了可访问性,因为我必须重新编译代码
因此,我的问题是,我如何才能获得第一种方法的灵活性,其中每个api被指定为一个资源,并且声明在数据库中被分配给一个资源,但仍然可以获得第二种方法的灵活性,其中我可以访问操作上下文并能够返回正确的状态编码响应?我们不希望必须重新编译代码以允许其他角色/声明访问webapi资源
我是索赔新手,所以我还没有完全理解所有的概念,所以如果我遗漏了什么,请告诉我。根据 “如果当前主体未被授权执行指定操作 在指定的资源上,将引发SecurityException;否则, 执行继续。” 然后,解决方案是在解决方案中创建一个异常处理程序,并返回一个未经授权的Http响应。(我真的认为ASP.Net在默认情况下做到了这一点,但我从未对此进行检查/反思:)
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);
}
}