c# – 基于客户端角色的身份验证?

目前,我正在使用OAuth和WebApi使用基于角色的身份验证对我的应用程序中的用户进行身份验证.我这样设置:

public override async Task GrantResourceOwnerCredentials (OAuthGrantResourceOwnerCredentialsContext context)
{
    var user = await AuthRepository.FindUser(context.UserName, context.Password);

    if (user === null)
    {
        context.SetError("invalid_grant", "The username or password is incorrect");
        return;
    }

    var id = new ClaimsIdentity(context.Options.AuthenticationType);
    id.AddClaim(New Claim(ClaimTypes.Name, context.UserName));

    foreach (UserRole userRole in user.UserRoles)
    {
        id.AddClaim(new Claim(ClaimTypes.Role, userRole.Role.Name));
    }

    context.Validated(id);
}

使用< Authorize>保护我的API路线标签.

但是,我已经遇到了一个问题,我的用户可以为不同的客户端担任不同的角色.例如:

用户A可以与多个客户端关联:客户端A和客户端B.
当从任一客户端访问信息时,用户A可以具有不同的“角色”.因此,用户A可以是客户端A的管理员和客户端B的基本用户.

这意味着,以下示例:

[Authorize(Roles = "Admin")]
[Route("api/clients/{clientId}/billingInformation")]
public IHttpActionResult GetBillingInformation(int clientId) 
{
    ...
}

用户A可以访问客户端A的帐单信息,但不能访问客户端B.

显然,我现在拥有的这种身份验证不起作用.设置客户端特定的基于角色的身份验证的最佳方法是什么?我可以简单地改变我现在拥有的东西,还是我必须完全以不同的方式设置它?

解决方法:

您可以删除authorize标记并在函数内部执行角色验证.

Lambda解决方案:

是否存在基于CustomerID和UserID添加的角色?
如果是这样,您可以执行类似下面示例的操作,根据您拥有的值获取客户,然后返回响应.

string userID = RequestContext.Principal.Identity.GetUserId();
var customer = Customer.WHERE(x => x.UserID == userID && x.clientId == clientId && x.Roles == '1')

您能否向我们提供有关您用于存储客户与用户之间的连接/角色的更多信息.

编辑:

以下是有关如何使用ActionFilterAttribute的示例.它从请求中获取CustomerId,然后从请求中获取标识的UserId.所以你可以用[UserAuthorizeAttribute]替换[Authorize]

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
    public class UserAuthorizeAttribute : System.Web.Http.Filters.ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            try
            {
                var authHeader = actionContext.Request.Headers.GetValues("Authorization").First();
                if (string.IsNullOrEmpty(authHeader))
                {
                    actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest)
                    {
                        Content = new StringContent("Missing Authorization-Token")
                    };
                    return;
                }

                ClaimsPrincipal claimPrincipal = actionContext.Request.GetRequestContext().Principal as ClaimsPrincipal;
                if (!IsAuthoticationvalid(claimPrincipal))
                {
                    actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest)
                    {
                        Content = new StringContent("Invalid Authorization-Token")
                    };
                    return;
                }

                if (!IsUserValid(claimPrincipal))
                {
                    actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest)
                    {
                        Content = new StringContent("Invalid User name or Password")
                    };
                    return;
                }

                //Finally role has perpession to access the particular function
                if (!IsAuthorizationValid(actionContext, claimPrincipal))
                {
                    actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest)
                    {
                        Content = new StringContent("Permission Denied")
                    };
                    return;
                }

            }
            catch (Exception ex)
            {
                actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest)
                {
                    Content = new StringContent("Missing Authorization-Token")
                };
                return;
            }

            try
            {
                //AuthorizedUserRepository.GetUsers().First(x => x.Name == RSAClass.Decrypt(token));
                base.OnActionExecuting(actionContext);
            }
            catch (Exception)
            {
                actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden)
                {
                    Content = new StringContent("Unauthorized User")
                };
                return;
            }
        }

        private bool IsAuthoticationvalid(ClaimsPrincipal claimPrincipal)
        {
            if (claimPrincipal.Identity.AuthenticationType.ToLower() == "bearer"
                && claimPrincipal.Identity.IsAuthenticated)
            {
                return true;
            }
            return false;
        }

        private bool IsUserValid(ClaimsPrincipal claimPrincipal)
        {
            string userID = claimPrincipal.Identity.GetUserId();
            var securityStamp = claimPrincipal.Claims.Where(c => c.Type.Equals("AspNet.Identity.SecurityStamp", StringComparison.OrdinalIgnoreCase)).Single().Value;

            var user = _context.AspNetUsers.Where(x => x.userID.Equals(userID, StringComparison.OrdinalIgnoreCase)
                && x.SecurityStamp.Equals(securityStamp, StringComparison.OrdinalIgnoreCase));
            if (user != null)
            {
                return true;
            }
            return false;
        }

        private bool IsAuthorizationValid(HttpActionContext actionContext, ClaimsPrincipal claimPrincipal)
        {
            string userId = claimPrincipal.Identity.GetUserId();
            string customerId = (string)actionContext.ActionArguments["CustomerId"];
            return AllowedToView(userId, customerId);
        }

        private bool AllowedToView(string userId, string customerId)
        {
            var customer = _context.WHERE(x => x.UserId == userId && x.CustomerId == customerId && x.RoleId == '1')
            return false;
        }
    }
上一篇:Vue 新手学习笔记:vue-element-admin 之登陆及目录权限控制


下一篇:Neo4j 文档