【问题标题】:ASP.NET Web Api with Role based authorization具有基于角色的授权的 ASP.NET Web Api
【发布时间】:2015-11-18 09:08:11
【问题描述】:

我正在使用基于 OWIN 令牌的身份验证的 Web API 2。唯一不起作用的是基于角色的授权。

在我的 AuthorizationServerProvider.GrantResourceOwnerCredentials 实现中,这是我分配角色的方式:

identity.AddClaim(client.ApplicationType == ApplicationTypes.WebClient
            ? new Claim(ClaimTypes.Role, "user")
            : new Claim(ClaimTypes.Role, "admin"));

但在控制器中使用 [Authenticate(Roles="user")] 只是向客户端返回授权被拒绝消息。我检查了变量,这就是里面的内容

所以角色似乎在那里,但是 user.Claims 是空的,并且 IsInRole("user") 也返回负数。

我在 stackoverflow 上发现了几个问题,从逻辑上讲,我看不出我错过了什么。我唯一想到的是覆盖授权命令,但这有点不必要,因为基于角色的授权似乎已经集成......

编辑:这就是我的工作方法的样子:

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
    var allowedOrigin = context.OwinContext.Get<string>("as:clientAllowedOrigin") ?? "*";
        context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin });

    Client client;
    using (var repo = new AuthRepository())
    {
        client = repo.FindClient(context.ClientId);
        if (client.ApplicationType != ApplicationTypes.Service)
        {
            var user = await repo.FindUser(context.UserName, context.Password);

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

【问题讨论】:

    标签: c# asp.net owin


    【解决方案1】:

    不要直接添加角色声明,而是使用 UserManager:

    UserManagerInstance.AddToRole(userId, "admin");
    

    这样,角色将被持久化(到 AspNetUserRoles 或您配置的任何内容),以便以后的请求可以使用。如果您直接添加声明,则不会发生这种情况,因为您将其添加到您的用户身份的“实例”中,该“实例”将随着当前请求而死亡。

    回答您的进一步要求:

    如果您希望将声明编码在票证上,那么您必须在按照您正在执行的方式添加声明后执行此操作(在 GrantResourceOwnerCredentials 中):

    var props = new AuthenticationProperties(new Dictionary<string, string>
            {
                { "userId", "blah,blah" },
                { "role", "admin" }
            });
    
    var ticket = new AuthenticationTicket(identity, props);
    context.Validated(ticket);
    

    这样您就不必“坚持”这类用户

    当然,您必须覆盖 OAuthAuthorizationServerProvider 的 TokenEndpoint 方法,以便在以后的请求/响应中检索这些数据。

        public override Task TokenEndpoint(OAuthTokenEndpointContext context)
        {
            foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
            {
                context.AdditionalResponseParameters.Add(property.Key, property.Value);
            }
    
            return Task.FromResult<object>(null);
        }
    

    【讨论】:

    • 这是永久性的吗?此解决方案的问题还在于,对于特定类型的客户端,我不需要用户并且希望尽可能直接将角色添加到上下文中
    • 嗨@dnanon 这个解决方案对你有用吗?我有同样的问题,你能分享一下你的 GrantResourceOwnerCredentials 方法吗?谢谢!
    • @JoseMiguelVegaLopez 我将我的方法的内容添加为问题的编辑
    【解决方案2】:

    可能以某种方式解决了它,但对我来说,如果我这样说它就可以了:

    [Authorize(Roles = "user")]
    [Route("")]
    [HttpGet]
    public async Task<IHttpActionResult> GetUserSpecificServers() { ... }
    

    【讨论】:

    • 不错的抓人。介意分享一下项目框架吗?
    猜你喜欢
    • 2016-11-18
    • 2018-06-14
    • 2019-05-27
    • 1970-01-01
    • 2021-03-12
    • 2020-05-19
    • 1970-01-01
    • 2016-12-10
    • 1970-01-01
    相关资源
    最近更新 更多