Skip to content

Commit b15e554

Browse files
authored
Merge pull request #8002 from genlin/main1224
AB#3171 Resolve IDX10501 Errors in a B2C Microsoft.Identity.Web Application
2 parents 543da41 + 63d4ffa commit b15e554

5 files changed

Lines changed: 199 additions & 0 deletions

File tree

78.9 KB
Loading
83.5 KB
Loading
21.2 KB
Loading
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
---
2+
title: Troubleshoot IDX10501 Error in ASP.NET Core app with Azure B2C Custom Policy
3+
description: Provides guidance for troubleshooting the IDX10501 error in ASP.NET Core with Azure B2C.
4+
ms.date: 01/06/2025
5+
ms.author: markbukovich
6+
ms.service: entra-id
7+
ms.custom: sap:Microsoft Entra App Integration and Development
8+
---
9+
10+
# IDX10501 error in ASP.NET Core app with Azure B2C custom policy
11+
12+
This guide discusses the cause of the "IDX10501" error, and provides a step-by-step solution to resolve it.
13+
14+
## Symptoms
15+
When you [implement a custom policy](/azure/active-directory-b2c/enable-authentication-web-application-options#pass-the-azure-ad-b2c-policy-id) in an ASP.NET Core application that integrates with Azure Active Directory B2C (Azure AD B2C), you might encounter the following IDX10501 error:
16+
17+
> IDX10501: Signature validation failed. Unable to match key: kid: '[PII of type 'System.String' is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'. Number of keys in TokenValidationParameters: '0'. Number of keys in Configuration: '1'. Exceptions caught: '[PII of type 'System.Text.StringBuilder' is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'. token: '[PII of type 'System.IdentityModel.Tokens.Jwt.JwtSecurityToken' is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
18+
19+
## Understanding the error
20+
21+
Why is this error generated when the custom policy redirects to your app? In ASP.NET Core, whenever a user is authenticated and authorized, and a redirect page exists to the web app that contains an ID token, ASP.NET Core middleware tries to validate this ID token to make sure that the redirect is genuine. To validate the ID token, the middleware requires the public key of the signing certificate that was used to sign the ID token. The middleware gets this public key by querying Azure Active Directory B2C. Specifically, the middleware uses a "metadata" endpoint in Azure Active Directory B2C that provides authentication information, including any public keys for signing certificates.
22+
23+
When you create a custom policy, you're required to create or upload a signing certificate. This signing certificate is different from that used for built-in user flows in Azure Active Directory B2C. This means that the public keys that are accessible from the "metadata" endpoint for your Azure Active Directory B2C won't contain the public key for your custom policy. The custom policy actually has its own metadata endpoint.
24+
25+
The endpoint that the middleware uses is configured by Microsoft.Identity.Web and is set at app startup. Because the metadata URL is already set, invoking a custom policy during runtime creates a scenario in which the middleware is looking at the wrong metadata URL while it validates the returning token.
26+
27+
## Solution
28+
29+
To resolve this issue, you must configure the correct metadata endpoint for the additional custom policy. To do this, create a second authentication scheme to handle the custom policy. By having this additional authentication scheme, you can set the correct metadata endpoint at startup. This process uses the following steps:
30+
31+
1. Add an additional redirect URI to your app registration.
32+
2. Configure an additional B2C authentication scheme in your app.
33+
3. Add an action to the desired controller.
34+
4. Implement the created action in the layout.
35+
36+
Code sample: [ASP.NET Core Web App with Custom B2C Policy](https://github.com/mbukovich/ExtraB2CPolicyMVC).
37+
38+
### Prerequisites
39+
40+
Before you continue this process, make sure that you have:
41+
42+
- An Azure B2C directory
43+
- An app registration for B2C authentication
44+
- [Standard user flows that are set up](/azure/active-directory-b2c/tutorial-create-user-flows?pivots=b2c-user-flow)
45+
- [A custom B2C policy that's added to your directory](/azure/active-directory-b2c/tutorial-create-user-flows?pivots=b2c-custom-policy)
46+
- An existing ASP.NET Core web app that's configured by having Microsoft.Identity.Web for B2C authentication
47+
48+
For more information, see [Enable authentication in your own web app by using Azure AD B2C](/azure/active-directory-b2c/enable-authentication-web-application?tabs=visual-studio)
49+
50+
### Step 1: Add an additional redirect URI
51+
52+
In the app registration, you have to add another redirect URI for the custom policy. In this case, you can't use the existing redirect URI because it could cause confusion for the web app. You'll be setting up two different authentication schemes. However, when the B2C policy redirects to the web app, the middleware won't know which authentication scheme to use. Therefore, you need a separate redirect URI to clearly distinguish between redirects from the existing and new authentication schemes.
53+
54+
Follow these steps:
55+
56+
1. Navigate to your app registration in the [Azure portal](https://portal.azure.com).
57+
2. In the **Manage** section, select **Authentication**.
58+
3. In the **Redirect URIs** section, select **Add URI**.
59+
4. Add a redirect URI. In this case, the new redirect URI is `https://localhost:44321/signin-oidc-editemail`.
60+
61+
:::image type="content" source="media/troubleshoot-error-idx10501-aspnet-b2c/add-redirect-uri.png" alt-text="Screenshot of adding Redirect URIs." lightbox="media/troubleshoot-error-idx10501-aspnet-b2c/add-redirect-uri.png":::
62+
63+
> [!NOTE]
64+
> Each custom policy requires its own redirect URI. For example, if you're adding two custom policies, you have to create two authentication schemes and two redirect URIs.
65+
66+
### Step 2: Configure an Additional Authentication Scheme
67+
68+
This process involves adding an action to your controller that issues a challenge to the user. Before you create this action, configure the app with an additional authentication scheme. This requires updating both the Appsettings.json file and the Startup.cs file.
69+
70+
#### Update `Appsettings.json`
71+
72+
Add the following configuration for your custom policy:
73+
74+
```json
75+
"<name-of-your-configuration>": {
76+
"Instance": "https://<B2C-tenant-name>.b2clogin.com",
77+
"ClientId": "<client-id-of-your-app-registration>",
78+
"CallbackPath": "/<endpoint-of-your-new-redirect-uri>",
79+
"SignedOutCallbackPath": "/signout/<built-in-sign-in-sign-up-policy>",
80+
"Domain": "<B2C-tenant-name>.onmicrosoft.com",
81+
"SignUpSignInPolicyId": "<built-in-sign-in-sign-up-policy>"
82+
},
83+
```
84+
85+
Example of `Appsettings.json`
86+
87+
```json
88+
{
89+
"AzureADB2C": {
90+
"Instance": "https://markstestorganization1.b2clogin.com",
91+
"ClientId": "09717d12-ca7f-4388-8393-dafe42c0c3a5",
92+
"CallbackPath": "/signin-oidc",
93+
"SignedOutCallbackPath": "/signout/B2C_1_signupsignin1",
94+
"Domain": "markstestorganization1.onmicrosoft.com",
95+
"SignUpSignInPolicyId": "B2C_1_signupsignin1",
96+
"ResetPasswordPolicyId": "B2C_1_PasswordReset1",
97+
"EditProfilePolicyId": "B2C_1_editProfileTest1"
98+
},
99+
"AzureADB2CEditEmail": {
100+
"Instance": "https://markstestorganization1.b2clogin.com",
101+
"ClientId": "09717d12-ca7f-4388-8393-dafe42c0c3a5",
102+
"CallbackPath": "/signin-oidc-editemail",
103+
"SignedOutCallbackPath": "/signout/B2C_1_signupsignin1",
104+
"Domain": "markstestorganization1.onmicrosoft.com",
105+
"SignUpSignInPolicyId": "B2C_1_signupsignin1"
106+
},
107+
"Logging": {
108+
"LogLevel": {
109+
"Default": "Information",
110+
"Microsoft": "Warning",
111+
"Microsoft.Hosting.Lifetime": "Information"
112+
}
113+
},
114+
"AllowedHosts": "*"
115+
}
116+
```
117+
**Important considerations**
118+
119+
- You can choose any name for the second B2C configuration. This configuration will be used for a single custom policy. If you have to add more custom policies, you must include additional B2C configurations in the AppSettings.json file. For this reason, we recommend that you give the JSON object a name that reflects the associated custom policy.
120+
- The CallbackPath value is the portion of the redirect URI that follows the domain. For example, if your redirect URI is `https://localhost:44321/signin-oidc-editemail`, then CallbackPath will be `/signin-oidc-editemail`.
121+
- You must include the standard built-in sign-up/sign-in user flow in the authentication scheme to make sure that users are prompted to sign in if they try to access your custom policy without being signed-in.
122+
123+
#### Update `Startup.cs`
124+
125+
Configure an additional authentication scheme in the Startup.cs file. In the `ConfigureServices` function, add the following code:
126+
127+
```csharp
128+
// Create another authentication scheme to handle extra custom policy
129+
services.AddAuthentication()
130+
.AddMicrosoftIdentityWebApp(Configuration.GetSection("<name-of-json-configuration>"), "<Arbitrary-name-for-Auth-Scheme>", "<Arbitrary-name-of-Cookie-Scheme>");
131+
132+
services.Configure<OpenIdConnectOptions>("<Arbitrary-name-for-Auth-Scheme>", options =>
133+
{
134+
options.MetadataAddress = "<Metadata-Address-for-Custom-Policy>";
135+
});
136+
```
137+
138+
- You have to set custom names for both your authentication scheme and the associated cookie scheme. Microsoft.Identity.Web will create these schemes by using the names that you specify.
139+
140+
- Replace `<name-of-json-configuration>` with the name of the JSON configuration from the previous step. Per the example in this article, this should be `AzureADB2CEditEmail`.
141+
142+
- Replace `<Your-Custom-Metadata-URL>` with the OpenID Connect discovery endpoint URL that's found under your custom policy in Azure AD B2C.
143+
144+
#### How to get the metadata address for custom policy
145+
146+
It's important to get the metadata address because this will be used by the middleware to get the required information to validate ID tokens that are returned by the custom policy.
147+
148+
To find the metadata address, follow these steps:
149+
150+
1. Log in to the Azure B2C portal.
151+
1. In **Policies** section, select **Identity Experience Framework**.
152+
153+
:::image type="content" source="media/troubleshoot-error-idx10501-aspnet-b2c/find-identity-exp-fr.png" alt-text="Screenshot of the Identity Experience Framework button.":::
154+
1. Select **Custom policies**, and then select the custom policy that you're using. In this case, it's **B2C_1A_DEMO_CHANGESIGNINNAME**.
155+
156+
:::image type="content" source="media/troubleshoot-error-idx10501-aspnet-b2c/custom-policy.png" alt-text="Screenshot of checking custom-policy.":::
157+
1. The metadata address is the URL that's listed under **OpenId Connect Discovery Endpoint**. Copy this URL, and paste it as the value for the `options.MetadataAddress` variable.
158+
159+
### Step 3: Add an action to the controller
160+
161+
In your controller, implement an action to trigger the Custom B2C Policy challenge for the user. In code sample, the action is added to the Home Controller for simplicity. Add the following code to your controller, and adjust the values and action name to meet your scenario. This code snippet can be found on line 40 of the `HomeController.cs` file in the `Controllers` folder in the code sample:
162+
163+
```csharp
164+
[Authorize]
165+
public IActionResult EditEmail()
166+
{
167+
var redirectUrl = Url.Content("~/");
168+
var properties = new AuthenticationProperties { RedirectUri = redirectUrl };
169+
properties.Items["policy"] = "B2C_1A_DEMO_CHANGESIGNINNAME";
170+
return Challenge(properties, "B2CEditEmail");
171+
}
172+
```
173+
174+
Make sure that `<Your-Custom-Policy>` matches your specific policy name and `<CustomAuthScheme>` is consistent with what you configured earlier.
175+
176+
### Step 4: Implement action in layout
177+
178+
Implement the action in the layout so that the user can actually invoke the custom policy. In the code sample, the following snippet adds a button alongside the existing B2C buttons, based on the [tutorial](/azure/active-directory-b2c/enable-authentication-web-application). The snippet is added to line 13 of the `_LayoutPartial.cshtml` file in the `Views/Shared` folder. Note that the `asp-controller` property is set to `Home` to reference the Home Controller, and the `asp-action property` is set to `EditEmail` to reference the action that's created in the Home Controller. For more information, see [Add the UI elements](/azure/active-directory-b2c/enable-authentication-web-application?tabs=visual-studio#step-4-add-the-ui-elements).
179+
180+
```html
181+
<li class="navbar-btn">
182+
<form method="get" asp-area="" asp-controller="Home" asp-action="EditEmail">
183+
<button type="submit" class="btn btn-primary">Edit Email</button>
184+
</form>
185+
</li>
186+
```
187+
188+
If you have an existing app that doesn’t use the partial layout, and you want only a quick link to test the custom policy, you can use the following tag to create a basic link. Make sure that you replace the indicated values and reference the correct controller if you didn’t add your action to the Home Controller.
189+
190+
```html
191+
<a asp-area="" asp-controller="Home" asp-action="replace-with-your-controller-action">Replace with text that describes the action</a>
192+
```
193+
194+
[!INCLUDE [Azure Help Support](../../../includes/azure-help-support.md)]

support/entra/entra-id/toc.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@
4747

4848
- name: Microsoft Entra App Integration and Development
4949
items:
50+
- name: Developing or registering apps
51+
items:
52+
- name: IDX10501 Error in ASP.NET Core with Azure B2C Custom Policy
53+
href: app-integration/troubleshoot-error-idx10501-aspnet-b2c.md
54+
5055
- name: Troubleshoot adding apps
5156
href: app-integration/troubleshoot-adding-apps.md
5257
items:

0 commit comments

Comments
 (0)