Skip to content

Commit 09572fd

Browse files
author
Simonx Xu
authored
Merge pull request #9333 from AmandaAZ/Branch-CI5973
AB#5973: Convert blog post to article
2 parents 26d998d + dce71bf commit 09572fd

2 files changed

Lines changed: 242 additions & 0 deletions

File tree

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
---
2+
title: Troubleshoot Access Token Signature Validation Errors
3+
description: Helps you troubleshoot access token signature validation errors and provides solutions in some scenarios.
4+
ms.date: 08/11/2025
5+
ms.reviewer: willfid
6+
ms.service: entra-id
7+
ms.custom: sap:Developing or Registering apps with Microsoft identity platform
8+
---
9+
# Troubleshoot access token signature validation errors
10+
11+
When a resource provider validates an access token's signature, signature validation errors occur. These errors might result from the signing key being unavailable or failing to validate the signature. This article helps you troubleshoot such errors and provides solutions in some scenarios.
12+
13+
## Step 1: Decode the access token
14+
15+
1. Get the access token being sent to the resource provider.
16+
1. Decode the access token and review the following claims:
17+
18+
- `aud` (Audience)
19+
- `iss` (Issuer)
20+
- `kid` (Key ID)
21+
22+
> [!NOTE]
23+
> You can decode access tokens using [https://jwt.ms](https://jwt.ms).
24+
25+
## Step 2: Validate the audience claim of the access token
26+
27+
If you send a Microsoft Graph access token to a non-Microsoft Graph resource provider, you get a signature validation error. Only Microsoft Graph can validate such token. The value of a Microsoft Graph token's `aud` claim is one of the following:
28+
29+
- `https://graph.microsoft.us`
30+
- `https://graph.microsoft.us/`
31+
- `https://graph.microsoft.com`
32+
- `https://graph.microsoft.com/`
33+
- `https://dod-graph.microsoft.us`
34+
- `https://dod-graph.microsoft.us/`
35+
- `00000003-0000-0000-c000-000000000000`
36+
37+
To resolve the signature validation error, ensure the correct access token is acquired for the resource provider and its `aud` claim is expected by the resource provider.
38+
39+
The audience claim of an access token is determined by the `scope` parameter that's sent in the request when acquiring access tokens. For example, to get an access token for `https://api.contoso.com`, use a scope like `https://api.contoso.com/read`.
40+
41+
For more information, see [Configure an application to expose a web API](/entra/identity-platform/quickstart-configure-app-expose-web-apis).
42+
43+
## Step 3: Validate the signing key
44+
45+
For other scenarios, the resource provider determines where to get the signing keys based on the OpenId Connect Metadata configuration and which signing key to use based on the `kid` claim of an access token. You can configure the OpenId Connect Metadata on the resource provider such as your custom API or API Authentication layer.
46+
47+
If you use a Microsoft authentication library like Microsoft Authentication Library (MSAL) or Microsoft Identity Web to authenticate an application, the default `MetadataAddress` that points to the OpenId Connect Metadata configuration is like `https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration`.
48+
49+
If you have configured a tenant ID, the `MetadataAddress` would be `https://login.microsoftonline.com/{tenant-id}/v2.0/.well-known/openid-configuration`. If you have configured an `Authority` like `https://login.microsoftonline.us/{tenant-id}`, the `MetadataAddress` would be `https://login.microsoftonline.us/{tenant-id}/v2.0/.well-known/openid-configuration`.
50+
51+
The OpenId Connect Metadata endpoint includes the `jwks_uri` property (also known as discovery keys endpoint), which specifies the location of signing keys. Depending on which OpenId Connect Metadata endpoint is used, it returns a different URL for the `jwks_uri` property. Here's a table that provides a few examples:
52+
53+
| Metadata endpoint | Discovery keys endpoint |
54+
| --- | --- |
55+
| `https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration` | `https://login.microsoftonline.com/common/discovery/v2.0/keys` |
56+
| `https://login.microsoftonline.com/{tenant-id}/v2.0/.well-known/openid-configuration`| `https://login.microsoftonline.com/{tenant-id}/discovery/v2.0/keys` |
57+
| `https://contosob2c.b2clogin.com/{tenant-id}/{policy}/v2.0/.well-known/openid-configuration` | `https://contosob2c.b2clogin.com/{tenant-id}/{policy}/discovery/v2.0/keys` |
58+
59+
The discovery keys endpoint includes multiple signing keys. If you use a specific key manually instead of the signing key provided in the access token, or your cached key, the signature validation might not succeed due to regular key rotations. For more details, see [Signing key rollover in the Microsoft identity platform](/entra/identity-platform/signing-key-rollover).
60+
61+
The content of discovery keys endpoint looks like this:
62+
63+
```json
64+
"keys": [
65+
{
66+
"kty": "RSA",
67+
"use": "sig",
68+
"kid": "<kid-value>",
69+
"x5t": "<x5t-value>",
70+
"n": "<n-value>",
71+
"e": "<e-value>",
72+
"x5c": [
73+
"<x5c-value>"
74+
],
75+
"issuer": "https://login.microsoftonline.com/{tenant-id}/v2.0"
76+
},
77+
```
78+
79+
The `kid` claim of the access token must match one of the keys available on the discovery keys endpoint based on the `kid` property. If it doesn't match, there are two possible reasons:
80+
81+
- Microsoft Entra ID and Azure Active Directory (AD) B2C use different signing keys.
82+
- The application is enabled for Security Assertion Markup Language (SAML) Single Sign-On (SSO).
83+
84+
To resolve this mismatch, go to [Step 4: Validate the iss claim of the access token](#step-4-validate-the-iss-claim-of-the-access-token).
85+
86+
## Step 4: Validate the iss claim of the access token
87+
88+
### Scenario 1: Microsoft Entra ID and Azure AD B2C use different signing keys
89+
90+
Check the `iss` claim of the access token. The `iss` claim indicates who issued the token:
91+
92+
- For Microsoft Entra ID-issued tokens, the `iss` claim has one of these formats:
93+
94+
- `https://sts.windows.net/{tenant-id}` (used for v1.0 tokens)
95+
- `https://login.microsoftonline.com/{tenant-id}/v2.0` (used for v2.0 tokens)
96+
97+
- For Microsoft Entra External ID-issued tokens, the `iss` claim has this format:
98+
99+
`https://{your-domain}.ciamlogin.com/{tenant-id}/v2.0/`
100+
101+
- For Azure AD B2C-issued tokens, the `iss` claim has this format:
102+
103+
`https://{your-domain}.b2clogin.com/tfp/{tenant-id}/{policy-id}/v2.0/`
104+
105+
To avoid signature validation errors, configure your OpenID Connect Metadata correctly based on the token issuer:
106+
107+
- For Microsoft Entra ID-issued tokens, make sure the OpenId Connect Metadata configuration looks like `https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration`.
108+
109+
For more information, see [OpenID Connect on the Microsoft identity platform](/entra/identity-platform/v2-protocols-oidc).
110+
111+
- For Microsoft Entra External ID-issued tokens, make sure the OpenId Connect Metadata configuration looks like `https://{tenant-domain}.ciamlogin.com/{tenant-id}/v2.0/.well-known/openid-configuration`.
112+
113+
For more information, see [Set up your OpenID Connect identity provider](/entra/external-id/customers/how-to-custom-oidc-federation-customers#set-up-your-openid-connect-identity-provider).
114+
115+
- For Azure AD B2C-issued tokens, make sure the OpenId Connect Metadata configuration looks like `<https://{your-domain}.b2clogin.com/{tenant-id}/{b2c-policy}/v2.0/.well-known/openid-configuration`.
116+
117+
For more information, see [Web sign in with OpenID Connect in Azure Active Directory B2C](/azure/active-directory-b2c/openid-connect).
118+
119+
### Scenario 2: The application is enabled for SAML SSO
120+
121+
Assume that the access token is issued from Microsoft Entra ID instead of Azure AD B2C. When an application in Microsoft Entra ID is enabled for SAML SSO, the signing key used to sign tokens is the SAML signing certificate. So, when you look for the `kid` claim from the access token on the default discovery keys endpoint, usually `https://login.microsoftonline.com/common/discovery/v2.0/keys`, it might not be listed.
122+
123+
We don't recommend using both OAuth2 and SAML for the same application. To resolve this issue, keep your application separate for OAuth2 and SAML by using one of the following methods:
124+
125+
- Create a new app registration for OAuth2 (recommended method).
126+
- Convert the enterprise application to use OAuth2 only.
127+
128+
To do so, disable SAML SSO by setting the `preferredSingleSignOnMode` property on the `servicePrincipal` to `null` or `oidc`.
129+
130+
- Update the OpenId Connect Metadata configuration of the resource provider to include `?appid={application-id}`, like `https://login.microsoftonline.us/<tenant-id>/v2.0/.well-known/openid-configuration?appid=<application-id>`.
131+
132+
> [!NOTE]
133+
> This solution is hard to implement and might not be possible depending on the resource provider.
134+
135+
## Examples of OpenId Connect Metadata configurations
136+
137+
Make sure you set the OpenId Connect Metadata configuration based on whether the access token is issued from Microsoft Entra ID or Azure AD B2C, or if adding `?appid={application-id}`.
138+
139+
Generally, configuring the Microsoft Entra ID `Instance` and `Tenant`, or `Authority` correctly can resolve signature validation errors.
140+
141+
- `Instance`
142+
143+
Microsoft Entra ID instance would be `https://login.microsoftonline.com`. For more information about Microsoft Entra ID instances, see [National clouds](/entra/identity-platform/authentication-national-cloud).
144+
145+
- `Tenant`
146+
147+
Tenant would be `contoso.onmicrosoft.com`. You can also use the Directory ID or any verified domain. We recommend using the Directory ID or the initial domain provided by Microsoft Entra ID (such as `contoso.onmicrosoft.com`).
148+
149+
- `Authority`
150+
151+
If you configure an `Authority`, `Instance` and `Tenant` aren't needed as `Authority` follows this format:
152+
153+
`{Instance}/{Tenant}`
154+
155+
So, `Authority` would be like `https://login.microsoftonline.com/contoso.onmicrosoft.com`.
156+
157+
Generally, the `MetadataAddress` is built based on the `Instance`/`Tenant`/`Authority` configuration and will automatically concatenate `/.well-known/openid-configuration` at the end. The following sections provide examples of manually specifying the `MetadataAddress`.
158+
159+
### Example 1: Use Microsoft Identity Web
160+
161+
```csharp
162+
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
163+
.AddMicrosoftIdentityWebApp(
164+
options =>
165+
{
166+
Configuration.Bind("AzureAd", options);
167+
options.MetadataAddress = metadataAddress,
168+
169+
})
170+
.EnableTokenAcquisitionToCallDownstreamApi(options => Configuration.Bind("AzureAd", options), initialScopes)
171+
.AddMicrosoftGraph(Configuration.GetSection("GraphAPI"))
172+
.AddInMemoryTokenCaches();
173+
```
174+
175+
For more details, see [Microsoft Identity Web customization](https://github.com/AzureAD/microsoft-identity-web/wiki/customization).
176+
177+
### Example 2: Use ASP.NET standard framework
178+
179+
- `UseWindowsAzureActiveDirectoryBearerAuthentication`
180+
181+
Set the metadata to `https://login.microsoftonline.com/{tenant-id}/.well-known/openid-configuration`.
182+
183+
```csharp
184+
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
185+
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
186+
{
187+
MetadataAddress = metadataAddress,
188+
Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
189+
```
190+
191+
- `UseOpenIdConnectAuthentication`
192+
193+
You can either set the `Authority` to `https://login.microsoftonline.com/{tenant-id}/v2.0`:
194+
195+
```csharp
196+
public void Configuration(IAppBuilder app)
197+
{
198+
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
199+
200+
app.UseCookieAuthentication(new CookieAuthenticationOptions());
201+
app.UseOpenIdConnectAuthentication(
202+
new OpenIdConnectAuthenticationOptions
203+
{
204+
// Sets the ClientId, authority, RedirectUri as obtained from web.config
205+
ClientId = clientId,
206+
Authority = authority,
207+
```
208+
209+
Or set the `MetadataAddress` to `https://login.microsoftonline.com/{tenant-id}/v2.0/.well-known/openid-configuration`:
210+
211+
```csharp
212+
public void Configuration(IAppBuilder app)
213+
{
214+
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
215+
216+
app.UseCookieAuthentication(new CookieAuthenticationOptions());
217+
app.UseOpenIdConnectAuthentication(
218+
new OpenIdConnectAuthenticationOptions
219+
{
220+
// Sets the ClientId, authority, RedirectUri as obtained from web.config
221+
ClientId = clientId,
222+
MetadataAddress = metadataAddress,
223+
```
224+
225+
### Example 3: Use Azure App Service authentication
226+
227+
Refer to [Configure your App Service or Azure Functions app to use Microsoft Entra sign-in](/azure/app-service/configure-authentication-provider-aad).
228+
229+
### Example 4: Use Azure API Management
230+
231+
Refer to [Secure an Azure API Management API with Azure AD B2C](/azure/active-directory-b2c/secure-api-management?tabs=app-reg-ga).
232+
233+
## References
234+
235+
[Validate tokens](/entra/identity-platform/access-tokens#validate-tokens)
236+
237+
[!INCLUDE [Azure Help Support](../../../includes/azure-help-support.md)]
238+
239+
240+

support/entra/entra-id/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@
8585
href: app-integration/serilog-protected-web-api-authentication-authorization-errors.md
8686
- name: Troubleshoot ASP.NET OWIN and ASP.NET Core authentication sign-in failures
8787
href: app-integration/asp-dot-net-open-web-interface-for-dot-net-core-authentication-sign-in-failures.md
88+
- name: Troubleshoot access token signature validation errors
89+
href: app-integration/troubleshooting-signature-validation-errors.md
8890
- name: WIF10201 No valid key mapping found
8991
href: app-integration/troubleshoot-wif10201-no-validkey-securitytoken-mvc.md
9092

0 commit comments

Comments
 (0)