Skip to content

Commit 068d93c

Browse files
authored
Merge pull request #8517 from MicrosoftDocs/genlin-patch-11
AB#3608 troubleshoot-rabc-issues-webassembly-auth-apps.md
2 parents c3f1cac + a1618f5 commit 068d93c

2 files changed

Lines changed: 122 additions & 8 deletions

File tree

support/entra/entra-id/app-integration/troubleshoot-rabc-issues-webassembly-auth-apps.md

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
---
2+
title: WebAssembly App Error - These requirements were not Met RolesAuthorizationRequirement in Microsoft Entra ID
3+
description: This article provides guidance to resolve role-based access control issues in developing WebAssembly authentication apps.
4+
ms.date: 03/20/2025
5+
ms.author: willfid
6+
ms.service: entra-id
7+
ms.custom: sap:Microsoft Entra App Integration and Development
8+
---
9+
10+
# Add role claim support in WebAssembly authentication in Microsoft Entra ID
11+
12+
This article provides guidance to resolve role-based access control issues in developing WebAssembly authentication apps.
13+
14+
## Symptoms
15+
16+
When you build a WebAssembly authentication app and try to implement role-based access control in the app, you receive the following error messages:
17+
- You are not authorized to access this resource.
18+
- Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]Authorization failed. These requirements were not met: RolesAuthorizationRequirement:User.IsInRole must be true for one of the following roles: (ROLE_NAME)
19+
20+
## Cause
21+
22+
The WebAssembly authentication stack might cast role claims into a single string. This prevents proper role-based access control.
23+
24+
## Solution
25+
26+
You can implement a custom user factory to modify the behavior of role claims mapping. To do this, follow these steps.
27+
28+
#### Step 1: Create a custom user factory
29+
30+
Create a custom User Factory (CustomUserFactory.cs):
31+
32+
```csharp
33+
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
34+
using Microsoft.AspNetCore.Components.WebAssembly.Authentication.Internal;
35+
using System.Security.Claims;
36+
using System.Text.Json;
37+
38+
public class CustomUserFactory : AccountClaimsPrincipalFactory<RemoteUserAccount>
39+
{
40+
public CustomUserFactory(IAccessTokenProviderAccessor accessor)
41+
: base(accessor)
42+
{
43+
}
44+
45+
public async override ValueTask<ClaimsPrincipal> CreateUserAsync(
46+
RemoteUserAccount account,
47+
RemoteAuthenticationUserOptions options)
48+
{
49+
var user = await base.CreateUserAsync(account, options);
50+
var claimsIdentity = (ClaimsIdentity?)user.Identity;
51+
52+
if (account != null && claimsIdentity != null)
53+
{
54+
MapArrayClaimsToMultipleSeparateClaims(account, claimsIdentity);
55+
}
56+
57+
return user;
58+
}
59+
60+
private void MapArrayClaimsToMultipleSeparateClaims(RemoteUserAccount account, ClaimsIdentity claimsIdentity)
61+
{
62+
foreach (var prop in account.AdditionalProperties)
63+
{
64+
var key = prop.Key;
65+
var value = prop.Value;
66+
if (value != null && (value is JsonElement element && element.ValueKind == JsonValueKind.Array))
67+
{
68+
// Remove the Roles claim with an array value, and create new claims with the same key
69+
claimsIdentity.RemoveClaim(claimsIdentity.FindFirst(prop.Key));
70+
var claims = element.EnumerateArray().Select(x => new Claim(prop.Key, x.ToString()));
71+
claimsIdentity.AddClaims(claims);
72+
}
73+
}
74+
}
75+
}
76+
```
77+
78+
#### Step 2: Add role mapping and custom user factory to your authentication middleware
79+
80+
If you're using `AddOidcAuthentication`:
81+
82+
```csharp
83+
84+
builder.Services.AddOidcAuthentication(options =>
85+
{
86+
builder.Configuration.Bind("AzureAd", options.ProviderOptions);
87+
options.ProviderOptions.AdditionalProviderParameters.Add("domain_hint", "contoso.com");
88+
options.ProviderOptions.DefaultScopes.Add("User.Read");
89+
options.UserOptions.RoleClaim = "roles";
90+
options.ProviderOptions.ResponseType = "code";
91+
}).AddAccountClaimsPrincipalFactory<CustomUserFactory>();
92+
```
93+
94+
If you're using `AddMsalAuthentication`:
95+
96+
```csharp
97+
builder.Services.AddMsalAuthentication(options =>
98+
{
99+
builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
100+
options.ProviderOptions.AdditionalScopesToConsent.Add("user.read");
101+
options.ProviderOptions.DefaultAccessTokenScopes.Add("api://{your-api-id}");
102+
options.UserOptions.RoleClaim = "roles";
103+
}).AddAccountClaimsPrincipalFactory<CustomUserFactory>();
104+
```
105+
106+
#### Step 3: Add the `Authorize` attribute to Blazor pages
107+
108+
```csharp
109+
@attribute [Authorize(Roles="access_as_user")]
110+
```
111+
112+
Next, add app roles to your app registration, assign a user to the app role, and then configure your app to use the assigned app role.
113+
114+
## References
115+
116+
- [Secure an ASP.NET Core Blazor WebAssembly standalone app with the Authentication library](/aspnet/core/blazor/security/webassembly/standalone-with-authentication-library)
117+
118+
- [GitHub project: Sample that has this solution implemented](https://github.com/willfiddes/aad-webassembly-auth)

support/entra/entra-id/toc.yml

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,9 @@
5555
href: app-integration/android-app-authentication-fails-after-published-to-google-play-store.md
5656
- name: WIF10201 No valid key mapping found
5757
href: app-integration/troubleshoot-wif10201-no-validkey-securitytoken-mvc.md
58-
- name: Get signed-in user groups from a group overage claim
59-
href: app-integration/get-signed-in-users-groups-in-access-token.md
60-
- name: Enable MSAL4J logging in a Spring Boot web application
61-
href: app-integration/enable-msal4j-logging-spring-boot-webapp.md
62-
- name: Cookies are disabled error in MSAL.Net app
63-
href: app-integration/script-errors-running-msal-net-xbap-app.md
58+
- name: Role-based access control issues in WebAssembly app
59+
href: app-integration/troubleshoot-rabc-issues-webassembly-auth-apps.md
60+
6461

6562
- name: Troubleshoot adding apps
6663
href: app-integration/troubleshoot-adding-apps.md
@@ -94,7 +91,7 @@
9491
- name: Error AADSTS50057 - user account is disabled
9592
href: app-integration/error-code-aadsts50057-user-account-is-disabled.md
9693
- name: AADSTS500011 - Resource Principal Not Found
97-
href: ./app-integration/error-code-aadsts500011-resource-principal-not-found.md
94+
href: app-integration/error-code-aadsts500011-resource-principal-not-found.md
9895
displayName: AADSTS500011
9996
- name: Error AADSTS500571 - guest user account is disabled
10097
href: app-integration/error-code-aadsts500571-guest-user-account-is-disabled.md
@@ -409,4 +406,3 @@
409406
href: user-prov-sync/exclude-user-primary-group.md
410407
- name: Yellow exclamation mark in Office 2013
411408
href: user-prov-sync/yellow-exclamation-mark-office2013.md
412-

0 commit comments

Comments
 (0)