IdentityServer / IdentityServer4

OpenID Connect and OAuth 2.0 Framework for ASP.NET Core
https://identityserver.io
Apache License 2.0
9.23k stars 4.02k forks source link

Can't access custom user claims from my MVC client #2213

Closed ZahFox closed 6 years ago

ZahFox commented 6 years ago

Ok, before I explain this issue in detail let me please first state that I've spent ALOT of time these last few weeks trying to make this framework work for my application(s). I've gone through every quick-start, read most of the docs, spent time watching videos on OAuth and OpenID, and even read through a lot of the example code projects here on GitHub. Everything is nearly in place except one very important part, claims..

My current projects are pretty much three of the applications from the quick-starts (for now): My Identity Server is one using EF Core to persist operational data and my users are persisted using ASP.Net Identity in a separate user database. The other two applications are the MVC client and the API resource. My main goal is to make the MVC client a GUI for accessing the API resource. This API resource should have a custom user claim associated with it that defines a user's role in the context of the API alone, but this is the one critical part I can't get just right. According to the docs, what I'm supposed to do is add custom IdentityResource on my IdentityServer. In my case this one is called "notus-role" (notus being the eventual name for my API)

defining-identity-resources

Ok, next I added an ApiResource that includes the previously created IdentityResource as a UserClaim (this is one of the parts I'm not so sure about..)

defining-api-resource

After that, I added an MVC client that has access to both the ApiResource and the IdentityResource

defining-mvc-client

Just to be thorough, here is the relevant section of the Startup.cs file for both the MVC client and API (MVC is the top image, API is the bottom image)

startup-for-mvc-client startup-for-api

Now comes one of the most confusing parts about all of this, (mostly because I haven't seen anywhere in the docs that mentions how to do this) adding a custom claim to the users. Naturally, having worked the ASP Identity before, I would assume that it is just like adding a claim to the Identity User, which I've done as you can see below:

seeding-admin-with-claims user-claims

Ok, now at this point, I've tested all of the applications and they work just fine, but as I've mentioned, this custom claim is an issue. What is strange is that when I call my API from the MVC client using the access token, my API client is able to see this custom claim:

user-identity-from-api

The main issue is that, from my MVC client, I can't seem to get this claim to appear no matter what I do (and yes I added its scope to startup file if you look in the picture from earlier on). There are only four claims I can ever see from the MVC client:

user-identity-from-mvc

This is an issue because I would like to make it so that the MVC client can authorize certain users for admin-like parts of the application using the notus-role. If you made it this far I really appreciate you taking the time to look this over. If you could provide some guidance it would be very appreciated (I'd be more than willing to contribute all of my code when I'm finished with this project for maybe a sample in the docs or something). Perhaps this is just me overlooking information that is already there, but I feel as if there isn't enough information in the docs explaining how custom claims and scopes are implemented. Yes, I understand how to define them, but I really have no idea how or when I can actually add that data a response/request (like what if I wanted a claim to be a list of user permissions or some custom data type). Get back to me when you can, any guidance would be a blessing.

Source Code for this project URL: https://bitbucket.org/ZahFox/asp-dot-net-core BRANCH: Test-IdentityServer4 Project Names:

  • Server - TestIdentity
  • MVC Client - TestIdentityServer-MVC-Client
  • API - TestIdentityServer4-API

Related Questions

  • Could you please clearly define the relationship between an IdentityResource and its claimTypes (are the claimTypes a 1-to-1 mapping of values from the aspnetuserclaims table in the User Database?)
  • In an API resource, are the UserClaims based on IdentityResources, or purely from the aspnetuserclaims table?
  • How can a profile be added as a claim? I see no table or any explanation of the format or process for dealing with profiles.
leastprivilege commented 6 years ago

Did you read this here as well:

https://leastprivilege.com/2017/11/15/missing-claims-in-the-asp-net-core-2-openid-connect-handler/

ZahFox commented 6 years ago

@leastprivilege No I didn't, but I followed along and this solved my issue! I really feel like this is something that should be more clearly explained how to handle in the documentation.

leastprivilege commented 6 years ago

Microsoft docs? Yea - totally agree. Tell @tratcher

Tratcher commented 6 years ago

Yeah... https://github.com/aspnet/Docs/issues/5106#issuecomment-356402957

snickler commented 5 years ago

@ZahFox @leastprivilege @Tratcher - I happened to come across the MapAllClaimsAction.

Using it seemed to do the trick for me.

                    options.ClaimActions.Add(new MapAllClaimsAction());
                    options.ClaimActions.DeleteClaim(JwtClaimTypes.Role);
                    options.ClaimActions.MapJsonKey(JwtClaimTypes.Role, JwtClaimTypes.Role, JwtClaimTypes.Role);

I did it this way instead of options.ClaimActions.MapAllExcept(JwtClaimTypes.Role); in order to maintain the ClaimsActions defined in the OpenIdConnectOptions (since MapAllExcept will clear all ClaimsActions first). This also makes sure that the role JToken doesn't add as an extra string JSON array of the roles you have defined.

mayankgaur commented 5 years ago

@leastprivilege No I didn't, but I followed along and this solved my issue! I really feel like this is something that should be more clearly explained how to handle in the documentation.

Hi I am also facing similar issue could you please elaborate what you have done I have tried all this method but still I am not having extra claims . options.SignInScheme = "Cookies"; options.Authority = "http://localhost:5000"; options.RequireHttpsMetadata = false; options.ClientId = "ecp_spa"; options.ClientSecret = "secret"; options.ResponseType = "id_token code"; options.SaveTokens = true; options.GetClaimsFromUserInfoEndpoint = true; options.Scope.Clear(); options.Scope.Add("openid"); options.ClaimActions.Remove("amr"); options.ClaimActions.Add(new MapAllClaimsAction()); options.ClaimActions.DeleteClaim(JwtClaimTypes.Role); options.ClaimActions.MapJsonKey(JwtClaimTypes.Role, JwtClaimTypes.Role, JwtClaimTypes.Role);

lock[bot] commented 4 years ago

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.