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):
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?