Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authorization roles WebAPI oauth owin

Tags:

I implemented a token authorization system on ASP.NET Web API with OWIN middleware. I successfully can authenticate with a REST client and obtain an authorization token to call the API. If I put the [Authorize] attribute on a GET action in my controller it also works correctly. If I don't have a valid token it denies the resource with a 401 message, but if I use [Authorize(Roles="admins")] with the roles parameter, it doesn't recognize the user's roles. I verified things in the database and checked that usersinroles is correctly filled.

This is a code snippet:

[Authorize(Roles = "admins")] public IEnumerable<CompanyModel> Get() {     ClaimsPrincipal principal = Request.GetRequestContext().Principal as ClaimsPrincipal;     bool isrole = principal.IsInRole("admins"); 

I also checked the action without the roles parameter and the isrole boolean is always false. Do I have to enable something?

like image 969
CaTourist Avatar asked Sep 04 '14 09:09

CaTourist


People also ask

What is Owin and OAuth?

OWIN (Open Web Interface for . NET) is a standard for an interface between . NET Web applications and Web servers. It is a community-owned open-source project. The OAuth authorization framework enables a third-party application to obtain limited access to a HTTP service.

How do you do role based authorization?

Each group has a set of permissions. For role-based authorization, the customer is responsible for providing the user ID, any optional attributes, and all mandatory user attributes necessary to define the user to Payment Feature Services. The customer must also define the roles that are assigned to the user.


1 Answers

You must add in GrantResourceOwnerCredentials method:

identity.AddClaim(new Claim(ClaimTypes.Role, "admins")); 

Step by step

In StartUp.cs class, you should have a custom provider, like the line

Provider = new CustomAuthorizationServerProvider() 

for example:

public void ConfigureOAuth(IAppBuilder app) {     OAuthAuthorizationServerOptions oAuthServerOptions = new OAuthAuthorizationServerOptions     {         AllowInsecureHttp = true,         TokenEndpointPath = new PathString("/token"),         AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),         Provider = new CustomAuthorizationServerProvider()     };      // Token Generation     app.UseOAuthAuthorizationServer(oAuthServerOptions);     app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()); } 

Then, your CustomAuthorizationServerProvider that inherits from OAuthAuthorizationServerProvider class will override GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context).

Then, after checking that the user has correct UserName and Password, you must add

var identity = new ClaimsIdentity(context.Options.AuthenticationType); ... // other claims ... identity.AddClaim(new Claim(ClaimTypes.Role, "admins")); ... var ticket = new AuthenticationTicket(identity, properties); context.Validated(ticket); 

Edited

You can get user roles from DB instead of using the "admins" harcoded string doing:

var roles = await userManager.GetRolesAsync(userId); 

So you can add the following method in your repository:

public async Task<IList<string>> UserRoles(string userId) {     IList<string> roles = await userManager.GetRolesAsync(userId);      return roles; } 

And then call it from your overrided GrantResourceOwnerCredentials adding:

using (AuthRepository repository = new AuthRepository()) {     IdentityUser user = await repository.FindUser(context.UserName, context.Password);      if (user == null)     {         context.SetError("invalid_grant", "The user name or password is incorrect");         return;     }      var roles = repository.UserRoles(user.Id); } 
like image 116
Xavier Egea Avatar answered Nov 07 '22 02:11

Xavier Egea