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
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;
}
}
}
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.
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.
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.
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.
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);
}
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() { ... }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With