I have a Web API that is protected by Azure AD. I am able to get access token for the Web API from Azure AD and use it successfully.
What I want to do is validate the token before performing any operation using that token so that I can give meaningful error messages to the user in case there's something wrong with the token. For example, some of the things I would like to tell user are:
However I am not able to do so because regardless of whether the token is valid or invalid, I am constantly getting the following error message:
IDX10516: Signature validation failed. Unable to match key:
kid: 'System.String'.
Exceptions caught:
'System.Text.StringBuilder'.
token: 'System.IdentityModel.Tokens.Jwt.JwtSecurityToken'. Valid Lifetime: 'System.Boolean'. Valid Issuer: 'System.Boolean'
I am successfully able to parse the token at https://jwt.io.
Under the "Header" section there, I see the following:
{
"typ": "JWT",
"alg": "RS256",
"x5t": "qDm8HXaLQBeSIvYXzMt8PQ_ADFt",//obfuscated
"kid": "qDm8HXaLQBeSIvYXzMt8PQ_ADFt"//obfuscated
}
Also, I get Signature Verified message as well as shown in the screenshot below.

Here's the code I wrote:
string authorizationToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Im5PbzNaRHJPRFhFSzFqS1doWHNsSFJfS1hFZyIsImt...";
try
{
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
TokenValidationParameters tokenValidationParameters = new TokenValidationParameters()
{
ValidateLifetime = true,
};
var claimsPrincipal = tokenHandler.ValidateToken(authorizationToken, tokenValidationParameters, out _);//Exception comes on this line.
}
catch (SecurityTokenExpiredException exception)
{
//Do something with the token expired exception
}
catch (SecurityTokenInvalidAudienceException exception)
{
//Do something with invalid audience exception
}
catch (Exception exception) //Code always lands in this exception block
{
//Token is invalid because of some other reason
}
As I said above, my code is always landing in the last exception block regardless of whether the token is valid or not.
Can anyone please tell me what I am doing wrong here? What is needed to successfully validate the token?
Any insights into this will be highly appreciated.
To validate the token, you need to specify the keys used by the identity provider (Azure AD) to sign the token:
using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static async Task Main(string[] args)
{
var token = "<my token>";
var tenantid = "<my azure ad tenant id>";
// => use to retrieve the keys used by AAD to sign the token
var openidConfigManaged = new ConfigurationManager<OpenIdConnectConfiguration>(
$"https://login.microsoftonline.com/{tenantid}/v2.0/.well-known/openid-configuration",
new OpenIdConnectConfigurationRetriever(),
new HttpDocumentRetriever());
var config = await openidConfigManaged.GetConfigurationAsync();
var parameteres = new TokenValidationParameters()
{
RequireAudience = true,
RequireExpirationTime = true,
ValidateAudience = true,
ValidateIssuer = true,
ValidateLifetime = true,
// The Audience should be the requested resource => client_id and or resource identifier.
// Refer to the "aud" claim in the token
ValidAudiences = new[] { "<my client id or resource identitifer>" },
// The issuer is the identity provider
// Refer to the "iss" claim in the token
ValidIssuers = new[] { $"https://sts.windows.net/{tenantid}/" },
IssuerSigningKeys = config.SigningKeys
};
var tokenHandler = new JwtSecurityTokenHandler();
var claimPrincipal = tokenHandler.ValidateToken(token, parameteres, out _);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With