简体   繁体   English

具有基于角色的授权的ASP.NET Web Api

[英]ASP.NET Web Api with Role based authorization

I am using Web API 2 with OWIN token based authentication. 我使用Web API 2与基于OWIN令牌的身份验证。 Only thing that is not working is authorization based on roles. 只有不起作用的是基于角色的授权。

In my implementation of AuthorizationServerProvider.GrantResourceOwnerCredentials this is how i assign roles: 在我的AuthorizationServerProvider.GrantResourceOwnerCredentials的实现中,这是我分配角色的方式:

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

But in the Controller using [Authenticate(Roles="user")] just returns a Authorization denied message to the client. 但是在使用[Authenticate(Roles =“user”)]的Controller中,只是向客户端返回授权拒绝消息。 I checked the variables and this is whats inside 我检查了变量,这是什么内部 在此输入图像描述

So the role seems to be there, but user.Claims is empty and IsInRole("user") also returns negative. 所以角色似乎存在,但user.Claims为空,IsInRole(“user”)也返回负数。

I found several questions here on stackoverflow and logic-wise i don't see what i missed. 我在stackoverflow和逻辑方面发现了几个问题,我没有看到我错过了什么。 Only thing that comes to my mind is overwriting the Authorize Command but this is kind of needless as role based authorization seems to be integrated already... 我想到的只是覆盖授权命令,但由于基于角色的授权似乎已经集成,所以这是不必要的......

EDIT: This is what my workig method looks like: 编辑:这是我的workig方法的样子:

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;
            }
        }
}

Don't add the role claim directly, use the UserManager instead: 不要直接添加角色声明,而是使用UserManager:

UserManagerInstance.AddToRole(userId, "admin");

That way the role will be persisted (to the AspNetUserRoles or whatever you have configured) so it will be there for the later requests. 这样,角色将被持久化(到AspNetUserRoles或您配置的任何内容),因此它将用于后续请求。 This doesn't happen if you add the claim directly, since you're adding it to an "instance" of your user identity that will die with the current request. 如果您直接添加声明,则不会发生这种情况,因为您将其添加到用户身份的“实例”中,该实例会因当前请求而死亡。

TO ANSWER YOUR FURTHER REQUIREMENTS: 回答您的进一步要求:

If you want the claims codified on the ticket then you have to do this after adding the claims the way you're doing (in GrantResourceOwnerCredentials): 如果您希望在票证上编制索赔,那么您必须按照您的方式添加索赔(在GrantResourceOwnerCredentials中):

var props = new AuthenticationProperties(new Dictionary<string, string>
        {
            { "userId", "blah,blah" },
            { "role", "admin" }
        });

var ticket = new AuthenticationTicket(identity, props);
context.Validated(ticket);

This way you don't have to "persist" these kind of users 这样您就不必“坚持”这类用户

Of course you would have to override the TokenEndpoint method of the OAuthAuthorizationServerProvider in order to retrive those data on later request/responses. 当然,您必须覆盖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);
    }

Probably solved it somehow, but for me it works if I put it like this: 可能以某种方式解决了它,但对我来说,如果我这样说它就有效:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM