xtreampb
xtreampb

Reputation: 562

Auth Roles in blazor server side

i'm using the latest dot net 8 and blazor app as a server side rendering. I'm trying to add role auth to the app. I've got my azure web app and app registration and authentication working. I added roles and assigned them to my user in entra id. When i step through my code i can see the roles claim and it has my custom role added to it. when i try to use the <AuthorizeView Roles="Spec.Read"><p>you have spec.read role</p> it never shows. here's what I got so far:

myComponent.razor

<AuthorizeView>
    <p>Hello, @context.User.Identity?.Name</p> @*shows my e-mail as expected*@
    <p>Roles: @roles</p> @*shows the roles that is populated in the code section as expected. this includes "Spec.Read" *@
    <AuthorizeView Roles="Spec.Read" Context="childContext">
        <p>you are a spec reader</p> @* this never shows up *@
    </AuthorizeView>
</AuthorizeView>
...
@code{
    [CascadingParameter]
    Task<AuthenticationState> authenticationState{ get; set; }
    
    string roles = "";

    protected override async Task OnInitializedAsync()
    {
        SpecList = await CosmosDataSource.GetSpecList();

        if(authenticationState is not null)
        {
            var userIdentity = (ClaimsIdentity)(await authenticationState).User?.Identity;
            var claims = userIdentity.Claims;
            roles = claims.Where(x => x.Type == "roles").Select(x => x.Value).Aggregate((prev, next) => $"{prev}; {next}");
        }

        await base.OnInitializedAsync();
    }
}

here is my program.cs snippet that i use to add ME ID (Microsoft Entra ID) and this seems to work. program.cs

...
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme).
    AddMicrosoftIdentityWebApp(builder.Configuration)
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddInMemoryTokenCaches();

// Add services to the container.
builder.Services.AddRazorPages().AddMvcOptions(options=>
{
    var policy = new AuthorizationPolicyBuilder()
                    .RequireAuthenticatedUser()
                    .Build();
    options.Filters.Add(new AuthorizeFilter(policy));
}).AddMicrosoftIdentityUI();
...

so how can I use my role claims to be used in the <AuthorizationView Roles=... section in my blazor component?

Also, I could be doing Auth completely wrong. this is my first time implementing auth and i'm trying to follow the MS docs but there is a bit of inconsistency throughout the docs and frameworks and net versions.

picture showing the roles working in the blazor

picture of the roles working

debugger showing the roles claim

Debugger showing the roles claim

EDIT:

I've updated my program cs add authentication to be the bellow snippet:

builder.Services.AddAuthentication("MicrosoftOidc")
    .AddOpenIdConnect("MicrosoftOidc", oidcOptions =>
    {
        oidcOptions.Scope.Add(OpenIdConnectScope.OfflineAccess);
        oidcOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        oidcOptions.Authority = builder.Configuration["AzureAd:Instance"];
        oidcOptions.ClientId = builder.Configuration["AzureAd:ClientId"];
        oidcOptions.ClientSecret = builder.Configuration["AzureAd:ClientSecret"];
        oidcOptions.ResponseType = OpenIdConnectResponseType.Code;
        oidcOptions.MapInboundClaims = false;
        oidcOptions.TokenValidationParameters.NameClaimType = JwtRegisteredClaimNames.Name;
        oidcOptions.TokenValidationParameters.RoleClaimType = "role";
        oidcOptions.TokenValidationParameters.IssuerValidator = AadIssuerValidator.GetAadIssuerValidator(
            oidcOptions.Authority,
            oidcOptions.Backchannel).Validate;
    })
    .AddMicrosoftIdentityWebApp(builder.Configuration)
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddInMemoryTokenCaches();

however I'm still getting the same result. I've tried changing the RoleClaimType to be "roles" as well with no chnage. the JsonWebTokenHandler.DefaultInboundClaimTypeMap has both role and roles defined but both point to the same role schema

Upvotes: 1

Views: 1244

Answers (1)

Taco
Taco

Reputation: 482

Have you defined the RoleClaimType? Because the default is ClaimTypes.Role (http://schemas.microsoft.com/ws/2008/06/identity/claims/role) but you use roles.

oidcOptions.MapInboundClaims = false;
oidcOptions.TokenValidationParameters.NameClaimType = JwtRegisteredClaimNames.Name;
oidcOptions.TokenValidationParameters.RoleClaimType = "roles";

See: https://learn.microsoft.com/en-us/aspnet/core/blazor/security/server/blazor-web-app-with-oidc?view=aspnetcore-8.0&pivots=without-bff-pattern

Upvotes: 1

Related Questions