用户或角色授权检查

时间:2018-12-12 14:10:26

标签: c# asp.net rest asp.net-web-api

我对授权有疑问。

说我有一个端点,例如: / 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();
}

没有更好的方法来做到这一点。我不想用这种检查弄乱我所有的端点功能。

3 个答案:

答案 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,我建议为其构建新服务。