Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Web Api with Role based authorization

Tags:

c#

asp.net

owin

I am using Web API 2 with OWIN token based authentication. Only thing that is not working is authorization based on roles.

In my implementation of AuthorizationServerProvider.GrantResourceOwnerCredentials this is how i assign roles:

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. I checked the variables and this is whats inside enter image description here

So the role seems to be there, but user.Claims is empty and IsInRole("user") also returns negative.

I found several questions here on stackoverflow and logic-wise i don't see what i missed. 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:

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;
            }
        }
}
like image 744
dnanon Avatar asked Nov 18 '15 09:11

dnanon


People also ask

What is role-based authorization in ASP NET Core?

Role-based authorization in ASP.NET Core. When an identity is created it may belong to one or more roles. For example, Tracy may belong to the Administrator and User roles whilst Scott may only belong to the User role. How these roles are created and managed depends on the backing store of the authorization process.

How do I use Auth0 role-based access control in web API?

Throughout this article, you learned how to use Auth0 Role-Based Access Control in your ASP.NET Web API. You started by defining and assigning roles to your users. Then, you registered a glossary Web API with Auth0 and enabled RBAC support. Next, you implemented an authorization policy in your Web API to check user permissions.

How to use getallemployees with role-based authentication in ASP NET?

The GetAllEmployees resource can be accessed by both the Admin and Superadmin resource. In order to achieve this, we need to implement Role-Based Authentication in ASP.NET Web API. Implementing Role-Based Basic Authentication in Web API. First, create an empty Web API application with the name RoleBasedBasicAuthenticationWEBAPI.

What is authorization in web API?

Authorization is deciding whether a user is allowed to perform an action. For example, Alice has permission to get a resource but not create a resource. The first article in the series gives a general overview of authentication and authorization in ASP.NET Web API.


2 Answers

Don't add the role claim directly, use the UserManager instead:

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. 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):

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.

    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);
    }
like image 167
Vi100 Avatar answered Nov 07 '22 14:11

Vi100


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() { ... }
like image 21
vladimir123 Avatar answered Nov 07 '22 14:11

vladimir123