Identityserver4: [Authorize(Roles="User Role")]

Created on 7 Feb 2017  路  13Comments  路  Source: IdentityServer/IdentityServer4

  • [X ] I read and understood how to enable logging

Issue / Steps to reproduce the problem

I followed the StackOverflow post to add Asp.Net Identity claims to the token. https://stackoverflow.com/questions/41687659/how-to-add-additional-claims-to-be-included-in-the-access-token-using-asp-net-id

When I log into QuickStart 6_AspNetIdentity MvcClient, the Home Secure.cshtml view displays

@foreach (var claim in User.Claims)
{

@claim.Type

@claim.Value

}

and the page display my roles, as displayed in the attached file. When I click either of the Call API links, User.Claims does not contain the my user roles. I put a code break in the Get() method. NameClaimType = "name" and RoleClaimType = "role" There are 13 claims, but none of them are my user role.
userroles

The user role is returned in the initial Login() call. How do I pass it back to the server to use [Authorize(Roles="User Role")]?

Thanks.

Relevant parts of the log file

<log goes here>
question

Most helpful comment

In the ApiResource configuration you should have something like:

new ApiResource("api1", "My API")
{
    UserClaims = {"role"}
}

All 13 comments

Thanks for the article. It is an interesting read. Unless I am missing something, I already have those things in place.

In the MvcClient startup.cs public void Configure() I have:

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "Cookies"
}

app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
AuthenticationScheme = "oidc",
SignInScheme = "Cookies",

Authority = "http://localhost:5000",
RequireHttpsMetadata = false,

ClientId = "mvc",
ClientSecret = "secret",

ResponseType = "code id_token",
Scope = { "api1", "offline_access" },

GetClaimsFromUserInfoEndpoint = true,
SaveTokens = true,

TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "role",
},
});

In IdentityServerWithAspNetIdentity startup.cs public void ConfigureServices(), I added
services.AddTransient();
services.AddTransient();

I created these class, based on the code from the aforementioned StackOverflow post.

Api startup.cs public void Configure() has:

app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
Authority = "http://localhost:5000",
RequireHttpsMetadata = false,
ApiName = "api1"
});

My first image shows the result of my login() call. User.Claims contains an entry type = "Role" value = "User Role" The second image shows the result of

public async Task CallApiUsingClientCredentials()
{
var tokenClient = new TokenClient("http://localhost:5000/connect/token", "mvc", "secret");
var tokenResponse = await tokenClient.RequestClientCredentialsAsync("api1");

var client = new HttpClient();
client.SetBearerToken(tokenResponse.AccessToken);
var content = await client.GetStringAsync("http://localhost:5001/identity/");

ViewBag.Json = JArray.Parse(content).ToString();
return View("json");

}

userroles

NameClaimType = "name" RoleClaimType = "role" Claims do not contain the claim that is present in the previous image (the result of my Login()).
inspector

Am I missing something?

Thanks

Is it your MVC or API code that can't see the roles?

I am using the IdentityServerWithAspNetIdentity, MvcClient, and Api projects from Quickstart 6_AspNetIdentity.

I added an action to MvcClient HomeController
[Authorize(Roles = "User Role")]
public IActionResult SecureWithRole()
{
ViewData["Message"] = "Secure page.";
return View();
}

I can confirm that works. It executes properly and, if I add a break, I can see that the User Role exists as a claim.

The API project is not receiving the User Role, but does receive the other claims. The API will be used with an EXE client, which I developed with IdentityModel. At the moment, I am using the MvcClient to test the API, to reduce the number of variables. I want to make sure that a user is not only authenticated, but has the proper role, in order to access the API. Is it possible to place the [Authenticate(roles="")] attribute on the API actions and pass the roles to the API?

The API project is not receiving the User Role

Sounds like you didn't configure a "role" entry in the UserClaim list for the ApiResource...?

I started with the default, Api project code
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
Authority = "http://localhost:5000",
RequireHttpsMetadata = false,
ApiName = "api1",
});

I changed that to
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
Authority = "http://localhost:5000",
RequireHttpsMetadata = false,
ApiName = "api1",

NameClaimType = "name",
RoleClaimType = "role",
SaveToken = true,

});

That does not work either. I am not clear on when I should use UseIdentityServerAuthentication and when I should use UseOpenIdConnectAuthentication. The MvcClient uses app.UseOpenIdConnectAuthentication. Should I replace this with app.UseOpenIdConnectAuthentication? Is there some other setting that I need to pass the roles?

Thanks.

In the ApiResource configuration you should have something like:

new ApiResource("api1", "My API")
{
    UserClaims = {"role"}
}

You make it look easy. Now, I have an MVC client and an EXE client that can both access an API, with user roles.

Thanks a lot.

It's like the matrix -- at some point it will all be clear :)

Some related questions:
At first I did't have ApiResoure configured but I had role array getting back in to oidc-client User object. At this point on my API side the roles didn't go through from a token as then I realized the roles wasn't present in the access_token.... so where where the roles where coming from in that case? Where the oidc-client User get the roles from? I was checking the both tokens none of them has roles.

Then I configured the ApiResoure as mentioned above and now I got the roles in my access_token, why it is working this way?

In your mvc client app claims you are getting values from id_token and api is called using access_token, so both have different claims as per configuration.

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings