0

I am having trouble getting the users Identity information from within the API. My project consists of a standalone WASM app, IDP and WebApi.

I have everything setup and it works but what I am after is a Call from the Blazor client to get some data from the api. The Api then uses the users email address to identify them and get the data just for them.

I have looked at similar questions and the solutions don't work for me on my project.

[HttpGet("GetData")]
        public async Task<IActionResult> GetData()
        {
            string test = User.Identity.Name; // returns null

            string username = "myuser@users.com";

            List<string> data= new List<string>();
            data= (await _dataRepository.GetData(username)).ToList();

            if (data.Count > 0)
            {
                return Ok(data);
            }
            else
            {
                return NoContent();
            }
        }

So where I am setting the username is there a way to get a hold of the email of the user who passed the request?

Edited Access Token:

  {
  "alg": "RS256",
  "kid": "2D49329C75FC43C78590AF6F6A0EFDB2",
  "typ": "at+jwt"
}

{
  "nbf": 1639243158,
  "exp": 1639246758,
  "iss": "https://localhost:5000",
  "aud": "https://localhost:5000/resources",
  "client_id": "ATS",
  "sub": "4892725f-f6da-4a28-827a-ce666bb6f098",
  "auth_time": 1638729064,
  "idp": "local",
  "jti": "53CB2F8FCB2EB34E3501E2C210B59B5D",
  "sid": "8463E4AA74D7369C1176249ED8FA46B1",
  "iat": 1639243158,
  "scope": [
    "openid",
    "profile",
    "MY_API"
    "email"
  ],
  "amr": [
    "pwd"
  ]
}
C-Sharpie
  • 195
  • 10
  • What authentication method are you using for the api? – Jeffery Dec 10 '21 at 11:36
  • Oidc Authentication – C-Sharpie Dec 10 '21 at 11:43
  • Please post a copy of your startup class where you configure the authentication and authorization., also post sample ID/Access token. – Tore Nestenius Dec 10 '21 at 11:48
  • // Authorization Policy var requireAuthenticationUserPolicy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .Build(); builder.Services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme) .AddIdentityServerAuthentication(options => { options.Authority = "https://localhost:5000/"; options.ApiName = "MY_API"; options.LegacyAudienceValidation = true; }); – C-Sharpie Dec 10 '21 at 11:58

1 Answers1

0

First you would typically secure your controller action methods using the [Authorize(...)] attribute and lookup the authorization in ASP.NET Core for more details about that.

Second, the most common problem when the name/email is not found is that you need to turn of the claims mapping using

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.Clear();

This is because by default Microsoft and OpenID have different opinions on what the claim names should be and because of that it can be wise to first clear this mapping and then secondly, point tell Microsoft what the name of the name/role claim by setting this:

opt.TokenValidationParameters.RoleClaimType = "roles";
opt.TokenValidationParameters.NameClaimType = "name";

For more details about claims mapping visit:

https://learn.microsoft.com/en-us/aspnet/core/security/authentication/claims?view=aspnetcore-6.0

Tore Nestenius
  • 16,431
  • 5
  • 30
  • 40
  • Hi I am using a global Authorization Policy so all controllers require Authorization. Is there any documentation / examples regarding the second bit for me to look into – C-Sharpie Dec 10 '21 at 11:58
  • The best way to understand what is going on is to put a breakpoint inside your controller and then just look at what claims are actually present in the User object and compare it against what is found in the token or in the UserInfo endpoint – Tore Nestenius Dec 10 '21 at 12:03
  • 1
    See my updated answer. – Tore Nestenius Dec 10 '21 at 12:04
  • What you need to do is also to add the name and email userclaims to the access token. (see ApiScope or ApiResources in IdentityServer) – Tore Nestenius Dec 10 '21 at 12:05
  • I have had a go at the above and I can see all the claims but how do I now retrieve the name/email in the API code? I am pulling in the profile so how do I get the Email address, I can do it in the Blazor Client but not the API. Sorry for the dumb questions but this is new to me. – C-Sharpie Dec 10 '21 at 22:32
  • As you see in your access token ,you do not have the email/name there, so there problem is in your Identityserver configuration and not in the API (so far). I assume the access token in the question is up-to-date. See my answer here: https://stackoverflow.com/questions/63811157/apiresource-vs-apiscope-vs-identityresource/63812939#63812939 – Tore Nestenius Dec 11 '21 at 12:13
  • I've included the email but I still get the same issue. The Name in my case is also the email but I have added email anyway. In the Blazor Client I can display the claims and get the value for example: name myemail@email.com | email myemail@email.com however what do I need to write in the API to get the values. I am currently getting "name" and "email" for the value where I should be getting "myemail@email.com" The confusing part is in the Blazor UI I can use AuthenticationState to get these claims so it must work. Is there a code example for the API of how to access it? – C-Sharpie Dec 11 '21 at 15:18
  • 1
    The name/email you see in the client/Blazor is based on the ID-token and not the access token. It is two different things. So the API does not see the ID-token, only the access-token. You need to know they are used separately. The client does not look at the content inside the access token. Can you update a new copy of your access token in the question? – Tore Nestenius Dec 11 '21 at 16:04
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/240049/discussion-between-c-sharpie-and-tore-nestenius). – C-Sharpie Dec 11 '21 at 17:24