Search code examples
asp.net-core-webapiauth0pkce

How to get User information from auth_token supplied by Auth0 tenant in PKCE flow


I have just successfully implemented the PKCE Flow from my Cordova Ionic5 mobile app which then uses the auth_token to authorize against my .NET Core 3.1 Web Api.

The problem is that I cannot access the user information from my .NET Core Web Api: name, email, etc.

I really need to know “who” the user is which just authenticated. Can you please help?

The PKCE flow enter image description here Code in my Startup.cs

services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(options =>
            {
                options.Authority = _configuration["Auth0:Domain"];
                options.Audience = _configuration["Auth0:Audience"];
            });

...

app.UseAuthentication();
app.UseAuthorization();


Solution

  • By default the access token wont have user information like name and email.

    Here's an example access token for a default authentication to an Auth0 tenant (using PKCE flow with SPA).

    {
      "iss": "https://example.auth0.com/",
      "sub": "auth0|REDACTED",
      "aud": [
        "REDACTED",
        "https://example.auth0.com/userinfo"
      ],
      "iat": 1599312415,
      "exp": 1599398815,
      "azp": "REDACTED",
      "scope": "openid profile email"
    }
    

    Your app should also receive an id_token, which might look like the following (assuming the request to /authorize includes the openid, profile, and email scopes).

    {
      "nickname": "joe.blogs",
      "name": "[email protected]",
      "picture": "REDACTED",
      "updated_at": "2020-09-04T10:21:07.315Z",
      "email": "[email protected]",
      "email_verified": false,
      "iss": "https://example.auth0.com/",
      "sub": "auth0|REDACTED",
      "aud": "REDACTED",
      "iat": 1599312415,
      "exp": 1599348415,
      "nonce": "REDACTED"
    }
    

    So you've got a couple options to get the name and email to your back-end API.

    1. In your app, parse the id_token JWT to get the name and email, and then explicitly pass these fields to your back-end API.
    2. You can enrich access token with name and email via Auth0 rules. Here is an example rule to add email to the access token (note: untested):
    function addAttributes(user, context, callback) {
      context.accessToken.email = user.email;
      callback(null, user, context);
    }
    

    see docs for Auth0 context object and user object to see what you've got access to...

    My thoughts are that option #1 is better approach because; a) I don't like to have PII in access tokens, and b) relying on access tokens to have information like name and email can lead to issues down the track (e.g. what happens if your back-end API also needs to get called with Auth0 M2M tokens that don't have this info).

    Finally in your .NET app, you can get the information you need by parsing the JWT in the Authorization HTTP header. Let me know if you need more information about this part (as I can help with this as well if needed)... just assuming the main issue is that you don't have the required user information in the JWT access token (which you should now if you follow my instructions)...