I'm building an app using Blazor WASM (which I'm new to.) I am using Auth0 for security. When I get the roles claim down to the front end Razor page, it does not interpret the roles correctly, and I'm about at my wits' end.
So! Starting from the server, I use JwtBearer so we can authenticate a couple of APIs using roles. That part works.
In the server's Program.cs:
...
builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, c =>
{
c.Authority = builder.Configuration["Auth0:Domain"];
c.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidAudience = builder.Configuration["Auth0:Audience"],
ValidIssuer = builder.Configuration["Auth0:Domain"]
};
});
var app = builder.Build();
...
Next, the client apparently wants to use OIDC? Okay, weird, but fine...
Client Program.cs
builder.Services.AddOidcAuthentication(options =>
{
builder.Configuration.Bind("Auth0", options.ProviderOptions);
options.ProviderOptions.ResponseType = "code";
options.ProviderOptions.AdditionalProviderParameters.Add("audience", builder.Configuration["Auth0:Audience"]);
// Without this setting, Blazor wants the role claim to be http://schemas.microsoft.com/ws/2008/06/identity/claims/role.
options.UserOptions.RoleClaim = "https://thiscompany.com/roles";
});
await builder.Build().RunAsync();
Finally, the Razor page. In this example, I wanted to have it show a login prompt if the user is not logged in (login being detected as Authorization with no roles), while only Admins can see the "hello world" message; it displays an unauthorized message to logged in users with any other roles. I've added some instrumentation to that message so I can see exactly what it's doing.
<AuthorizeView>
<Authorized>
<AuthorizeView Roles="Admin">
<Authorized Context="loggedInUser">
<PageTitle>Administration Center</PageTitle>
<h1>Hello, world!</h1>
</Authorized>
<NotAuthorized Context="loggedInUser">
<p>YOU ARE NOT WELCOME HERE</p>
<p>Claims: <ul>
@for(int i = 0; i < Claims(context).Count; i++)
{
<li>@Claims(context)[i]</li>
}
</ul>
</p>
<p>Role claim: @RoleClaim(context)</p>
<p>Is Admin in @GetRoleClaimType(context)? @context.User.IsInRole("Admin")</p>
</NotAuthorized>
</AuthorizeView>
</Authorized>
<NotAuthorized>
<PageTitle>The Admin-Only App</PageTitle>
<h1>The Admin-Only App</h1>
Please log in to access this application.
</NotAuthorized>
</AuthorizeView>
If I log in and I have the Admin role, I should see "Hello world". Instead, here's what happens:
YOU ARE NOT WELCOME HERE
Claims:
• https://thiscompany.com/roles: ["Admin","SomeOtherRole"]
<...other irrelevant claims...>
Role claim: https://thiscompany.com/roles:["Admin","SomeOtherRole"]
Is Admin in https://thiscompany.com/roles? False
My understanding was that it was supposed to decompose the roles array and grant me access, but it doesn't. If I tinker with Auth0 so that I get the claim:
https://thiscompany.com/roles: Admin
Then it works correctly, so I have a sneaking suspicion that the JSON array is getting encoded so that it decodes as a text string. However, using the array of roles as provided is a requirement. I'm really lost in the weeds here and not sure where or how to adjust this so that Blazor can understand the roles claim.