Skip to content
This repository has been archived by the owner on Dec 13, 2022. It is now read-only.

Dotnet 2.0 migration sub claim is missing #1707

Closed
1 task done
activebiz opened this issue Nov 5, 2017 · 14 comments
Closed
1 task done

Dotnet 2.0 migration sub claim is missing #1707

activebiz opened this issue Nov 5, 2017 · 14 comments
Labels

Comments

@activebiz
Copy link

activebiz commented Nov 5, 2017

  • I read and understood how to enable logging

Issue / Steps to reproduce the problem

  • Migration from dotnet core 1.1 to 2.0.
  • Implicit grant
  • No in memory stores.

The Auth server successfully issues the token and redirect back to the client. The token looks are shown below.

When trying to make an api call using the token, one of the call gets user Id which uses
IdentityServer4.Extensions.PrincipalExtensions.GetSubjectId() method at which point it throws below error as shown in the log.
...

The AuthToken has got sub in the token as follows:

user : t
access_token : "eyJhbGciOiJSUzI1NiIsImtpZCI6Ijg5MjYwQjUzQTc1NUUyQzQ0N0Q5NDA0OTY..."
expires_at : 15098723469
id_token : "eyJhbGciOiJSUzI1NiIsImtpZCI6Ijg5MjYwQjUzQTc1NUUyQzQ0N0Q5NDA0OTY5NjQ3MTYzMTU..."
profile : AspNet.Identity.SecurityStamp :
"xxxxxx-xxxx-xxxx-xxx"
amr :["external"]
auth_time:15098703455
email:"xyz@xyz.xyz"
email_verified:false
idp:"local"
name:"foobar"
phone_number:"111"
phone_number_verified:true
preferred_username:"a@a.com"
role:"Admin"
sid:"c7c99cb4b62b33e9f88b02db3esdfsdf"
sub:"69"

Api.Startup.cs

        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                    .AddJwtBearer(options =>
                    {
                        // base-address of your identityserver
                        options.Authority = "url_to_auth_server";

                        // name of the API resource
                        options.Audience = "api";
                        options.RequireHttpsMetadata = false;
                        options.TokenValidationParameters = new TokenValidationParameters()
                        {
                            ValidateLifetime = false,
                            ValidateIssuer = false,
                            ValidateAudience = false,
                        };
                    });

Tried https://github.com/IdentityServer/IdentityServer4/issues/1545 but no luck.

Relevant parts of the log file

ERR] Error occured while getting ...
System.InvalidOperationException: sub claim is missing
   at IdentityServer4.Extensions.PrincipalExtensions.GetSubjectId(IIdentity identity)
@leastprivilege
Copy link
Member

Sorry - this does not make any sense to me.

Can you describe in more detail what you are actually doing?

@activebiz
Copy link
Author

@leastprivilege Apologies about this. This happens when trying to make an api call. I have updated the text above.

@leastprivilege
Copy link
Member

why do you use IdentityServer4.Extensions.PrincipalExtensions.GetSubjectId() in your apis?

Inspect the user's claims in your API and see what you get.

@activebiz
Copy link
Author

activebiz commented Nov 6, 2017

@leastprivilege One of the requirement is to get user Id for each api request. I know GetSubjectId may not be best way to achieve this. So you are saying just create a custom claim for the userId and use that?

Btw I haven't done any coding to put the sub in the token this happens by IdentityServer so I thought I just use that. Is this not a good approach?

@leastprivilege
Copy link
Member

What I am saying is - why do you have a dependency on the IdentityServer DLL in your API. All this method does is search for the subject claim.

As I said - inspect the claims collection in your API and see what's on there.

@activebiz
Copy link
Author

Thanks for the quick response. I'll try that and update it here.

@TomCJones
Copy link

what's wrong with the sub? It's the one that's always there

@activebiz
Copy link
Author

activebiz commented Nov 7, 2017

@TomCJones so did I thought. But I am getting http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier instead of sub.

So I had to update the API server startup.cs as follows and that fixed the issue.

        JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); // <-- This is the fix
        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                    .AddJwtBearer(options =>
                    {
                        // base-address of your identityserver
                        options.Authority = "url_to_auth_server";

                        // name of the API resource
                        options.Audience = "api";
                        options.RequireHttpsMetadata = false;
                        options.TokenValidationParameters = new TokenValidationParameters()
                        {
                            ValidateLifetime = false,
                            ValidateIssuer = false,
                            ValidateAudience = false,
                        };
                    });

@leastprivilege None of the claims collection had the sub/userId in it.

I sort of understand why that one line made it work but I would appriciate if someone put some details here.

@leastprivilege
Copy link
Member

Thank Microsoft for that. They do a mapping of the inbound standard claims to their proprietary ones...

Glad you found it!

@lvanderbijl
Copy link

I'm getting the same issue when I upgraded to .net core 2.0. This was working fine pre 2.0.

I am using open id connect to authenticate against azure ad.

I can indeed use the above solution to get past the assertion errors, but then all the claims names are different than what they used to be.

Is there anyway to get the original behaviour back?

@lvanderbijl
Copy link

It appears as though azure ad does correct send claim types including a "sub" claim. As @leastprivilege mentions above, ms, for some reason, thinks it's a good idea translate inbound claims into their own bespoke claims.

@leastprivilege is there a reason for the need to assert a sub? Is that part of a spec?

@TomCJones
Copy link

OpenID Connect requires sub - from the spec
sub
REQUIRED. Subject Identifier. A locally unique and never reassigned identifier within the Issuer for the End-User, which is intended to be consumed by the Client, e.g., 24400320 or AItOawmwtWwcT0k51BayewNvutrJUqsvl6qs7A4. It MUST NOT exceed 255 ASCII characters in length. The sub value is a case sensitive string.

@tylerje
Copy link

tylerje commented Dec 9, 2017

@activebiz -- I found your comment very helpful, though I remembered seeing another reference somewhere that was a bit more surgical and found that this worked great:

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub");

@lock
Copy link

lock bot commented Jan 13, 2020

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.

@lock lock bot locked as resolved and limited conversation to collaborators Jan 13, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

5 participants