How to get phone in Okta claims

I’m using IdentityServer4/.NET 6.0 and Okta to implement SSO.

We are using Authorziation Code flow.

Here is my setup:

public void ConfigureServices(IServiceCollection services)
{
    services
        .AddControllersWithViews()
        .AddNewtonsoftJson();
    services.AddAuthentication()
        .AddCookie("Cookies")
        .AddOpenIdConnect("oidc", "OpenIdConnect", options =>
        {
            options.GetClaimsFromUserInfoEndpoint = true; // doesn't work
            options.SignInScheme = "idsrv.external";
            options.SignOutScheme = "idsrv.external";
            options.Authority = "https://mysaas.oktapreview.com";
            options.ClientId = "0oa1ml149rjc2sybG0h2";
            options.ClientSecret = "secretHere";
            options.ResponseType = "code";
            options.Scope.Add("email"); // this works
            options.Scope.Add("phone"); // this doesn't work
            options.Events = new MyOpenIdConnectEvents();
        });
}
public class MyOpenIdConnectEvents : OpenIdConnectEvents
{
    public MyOpenIdConnectEvents()
    {
        OnTokenValidated = OnTokenValidatedImpl;
        OnUserInformationReceived = OnUserInformationReceivedImpl;
    }

    private Task OnTokenValidatedImpl(TokenValidatedContext context)
    {
        context.Success();
        return Task.CompletedTask;
    }

    private Task OnUserInformationReceivedImpl(UserInformationReceivedContext context)
    {
        // Never gets executed
        return Task.CompletedTask;
    }
}

This method is called via the Login() method:

private IActionResult ForwardToIdentityProvider(string returnUrl, string loginHint)
{
    var callbackUrl = Url.Action(nameof(Callback));
    const string provider = "oidc";
    var props = new AuthenticationProperties
    {
        RedirectUri = callbackUrl,
        Items =
        {
            { "scheme", provider },
            { "returnUrl", returnUrl },
            { "loginHint", loginHint }
        }
    };

    return Challenge(props, provider);
}

This is where I access the claims:

[HttpGet]
public async Task<IActionResult> Callback()
{
    var result = await HttpContext.AuthenticateAsync("idsrv.external");
    var claims = result.Principal.Claims.ToList();
    // Code omitted for brevity
    return Ok();
}

The claims object has this (notice there is no phone claim):
image

You can see the scopes are in the URL:

I’ve set up the default authorization server in Okta to have a phone scope/claim:

I can see the phone coming through in the token preview:

Is phone meant to come through via the UserInfoEndpoint?

If so, since I have options.GetClaimsFromUserInfoEndpoint = true, why doesn’t the OnUserInformationReceivedImpl() method get executed?

I noticed email comes through even without having set up a custom claim/scope in Okta.

How can I access the phone claim?

If you are using the Org Authorization Server (which it looks like you may be, based on the Authority you’ve set), then yes, the phone_number should be available at in the Userinfo response instead of within the ID token itself, as described here.

If you do take the user’s Access Token and send it to the Userinfo endpoint manually, do you see the phone_number claim returned?

Keep in mind that if you are in fact using the Org Authorization Server, testing in Token Preview will not be a good representation of the information that will be available in your tokens, as Token Preview only exists for Custom Authorization Servers and will not be an exact match of the data returned via the Org Authorization Server.

I’m using the org authorization server.
I just tested the UserInfoEndpoint using Postman and cannot see the phone_number claim:

I added the phone claim to the default custom authorization server and can see it come through in the claims from the /userinfo endpoint. Do I have to use this custom authZ server or can I set up the org one to return the phone claim?

The Org Authorization Server is capable of returning user phone numbers, but it typically pulls from the Application User Profile.

Did you request the phone scope when you requested the tokens? If yes, can you also check that the Phone Number is being mapped from the Okta User Profile into the Application User Profile?