I have an Angular 10 application that authenticates with Azure AD using oidc. It successfully gets the token and then makes a REST call to a WCF service (.net framework 4.7) sending the token it received from Azure. The validation code in the WCF Service fails with the following error: IDX10511: Signature validation failed. Keys tried: 'System.Text.StringBuilder'. kid: 'System.String'. Exceptions caught: 'System.Text.StringBuilder'. token: 'System.IdentityModel.Tokens.Jwt.JwtSecurityToken'.
If I authenticate using Auth0, the same WCF code is able to validate the jwt from Auth0 with no errors.
Below is the UserManagerSettings for my oidc client:
this.stsSettings = {
authority: "https://login.microsoftonline.com",
client_id: myclientId,
redirect_uri: `${myclientRoot}signin-callback`,
scope: "openid profile email",
response_type: "code",
loadUserInfo: false, // setting loadUserInfo to true causes error because CORS blocks the call to the user info endpoint.
post_logout_redirect_uri: `${myclientRoot}signout-callback`,
silent_redirect_uri: `${myclientRoot}assets/silent-callback.html`,
metadata: {
issuer: `${mystsAuthority}/${mytenantId}/v2.0`,
authorization_endpoint: `${mystsAuthority}/${mytenantId}/oauth2/v2.0/authorize`,
token_endpoint: `${mystsAuthority}/${mytenantId}/oauth2/v2.0/token`,
"jwks_uri": `https://login.microsoftonline.com/${mytenantId}/discovery/v2.0/keys`,
}
My C# code in the WCF Service to validate the token
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
JwtSecurityToken jwtToken = tokenHandler.ReadToken(token) as JwtSecurityToken;
if (jwtToken == null)
{
return null;
}
IConfigurationManager<OpenIdConnectConfiguration> configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>($"{Properties.Settings.Default.ValidIssuer.TrimEnd('/')}/.well-known/openid-configuration", new OpenIdConnectConfigurationRetriever());
OpenIdConnectConfiguration openIdConfig = await configurationManager.GetConfigurationAsync(CancellationToken.None);
var validationParameters = new TokenValidationParameters()
{
LifetimeValidator = LifetimeValidator,
ValidAudiences = new[] { Properties.Settings.Default.CommaDelimitedValidAudiences },
AudienceValidator = AudienceValidator,
ValidIssuer = Properties.Settings.Default.ValidIssuer,
ValidateLifetime = true,
RequireExpirationTime = true,
ValidateIssuer = true,
ValidateAudience = true,
ValidateIssuerSigningKey = false,
IssuerSigningKeys = openIdConfig.SigningKeys,
RequireSignedTokens = false
};
SecurityToken securityToken;
var principal = tokenHandler.ValidateToken(token, validationParameters, out securityToken);
return principal;
}
catch (Exception ex)
{
return null;
}
The exception occurs at the code tokenHandler.ValidateToken(token, validationParameters, out securityToken);
I tried various online suggestions, adding a scope in Azure, the workaround for "a 0 byte prefix.", etc and they didn't work.
I've been on this too long and am running out of ideas.
Please help.
Thanks,