我对授权有疑问。
说我有一个端点,例如: / users / {id} / password
说这是一个发布请求,并允许您更改特定用户的密码。
是否有一种方法可以授权/仅允许当前登录的用户或具有特定角色的任何用户使用此端点。 (此信息可在访问令牌的声明中找到)
这是否可能是第一个问题...
如果是这样,那么我了解到既有基于角色的授权又有基于声明的授权,因为它们(从我看来)使用他们检查的特定值。因此,这将适用于角色,但不适用于用户ID,因为它是动态的,并且例如在创建Polocy时无法编写所有ID进行检查。
我需要对照令牌用户ID检查请求的用户ID,以检查他们是否被授权使用端点。如果不是,那么他们是管理员吗?如果可以,那么他们不是目标用户,则可以随时进行更改。
我似乎也找不到在两种情况下使用的两种不同授权集的示例(例如,在这里,如果您将其作为目标用户或管理员,则可以使用它)
我目前在端点中通过获取身份并手动检查声明来解决此问题。
var identity = (ClaimsIdentity)User.Identity;
IEnumerable<Claim> claims = identity.Claims;
var userDataClaim = claims.Where(x => x.Type == ClaimTypes.UserData).FirstOrDefault();
var roleClaim = claims.Where(x => x.Type == ClaimTypes.Role).FirstOrDefault();
if(Convert.ToInt32(userDataClaim.Value) != id && roleClaim.Value != "1")
{
return Unauthorized();
}
没有更好的方法来做到这一点。我不想用这种检查弄乱我所有的端点功能。
答案 0 :(得分:1)
您可以像这样在端点之前添加它。
[Authorize(Roles = "admin")]
还要使 Roles 检查成为可选检查,您还必须继承System.Web.Http.AuthorizeAttribute
类并覆盖HandleUnauthorizedRequest
方法,在此方法中,您可以添加一些检查选项就像您要在每个端点中添加一样。
答案 1 :(得分:1)
您将必须构建自己的自定义授权属性。 这很简单,如果仅调整它以检查当前登录的用户,则可以使用AuthorizeAttribute的相同定义。 看一下this。 (AuthorizeAttribute.cs)
protected virtual bool IsAuthorized(HttpActionContext actionContext)
{
if (actionContext == null)
{
throw Error.ArgumentNull("actionContext");
}
IPrincipal user = actionContext.ControllerContext.RequestContext.Principal;
if (user == null || user.Identity == null || !user.Identity.IsAuthenticated)
{
return false;
}
if (_usersSplit.Length > 0 && !_usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase))
{
return false;
}
if (_rolesSplit.Length > 0 && !_rolesSplit.Any(user.IsInRole))
{
return false;
}
return true;
}
如果要根据声明进行验证,可以修改IsAuthorized并通过以下方式进行操作:
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);
答案 2 :(得分:0)
如果(userId = currentUser){ 从其访问令牌获取userInfo } 其他{ 从数据库获取用户管理员信息 } 我将为此建议中间件。您需要身份验证角色并获取userInfo,我建议为其构建新服务。