79093244

Date: 2024-10-16 08:56:44
Score: 0.5
Natty:
Report link

After my test, you can create a custom user factory in the Client application, and you need to manually enable role declaration. Here is an example for your reference: In the database, I added and bound the role information of an account:

enter image description here

enter image description here

In my client, I configured a CustomUserFactory, which inherits AccountClaimsPrincipalFactory, which is used to create a ClaimsPrincipal object, contains the user's identity information and claims:

public class CustomUserFactory(IAccessTokenProviderAccessor accessor)
    : AccountClaimsPrincipalFactory<RemoteUserAccount>(accessor)
{
    public override async ValueTask<ClaimsPrincipal> CreateUserAsync(
        RemoteUserAccount account,
        RemoteAuthenticationUserOptions options)
    {
        var user = await base.CreateUserAsync(account, options);

        if (user.Identity is not null && user.Identity.IsAuthenticated)
        {
            var identity = (ClaimsIdentity)user.Identity;
            var roleClaims = identity.FindAll(identity.RoleClaimType).ToArray();

            if (roleClaims.Any())
            {
                foreach (var existingClaim in roleClaims)
                {
                    identity.RemoveClaim(existingClaim);
                }

                var rolesElem =
                    account.AdditionalProperties[identity.RoleClaimType];

                if (options.RoleClaim is not null && rolesElem is JsonElement roles)
                {
                    if (roles.ValueKind == JsonValueKind.Array)
                    {
                        foreach (var role in roles.EnumerateArray())
                        {
                            var roleValue = role.GetString();

                            if (!string.IsNullOrEmpty(roleValue))
                            {
                                identity.AddClaim(
                                  new Claim(options.RoleClaim, roleValue));
                            }

                        }
                    }
                    else
                    {
                        var roleValue = roles.GetString();

                        if (!string.IsNullOrEmpty(roleValue))
                        {
                            identity.AddClaim(
                              new Claim(options.RoleClaim, roleValue));
                        }
                    }
                }
            }
        }

        return user;
    }
}

Then in the Client application, register the factory in the Program file and add role-related services:

builder.Services.AddApiAuthorization(options =>
{
    options.UserOptions.RoleClaim = "role";
}).AddAccountClaimsPrincipalFactory<CustomUserFactory>();

In the Server application: Configure the Identity server:

builder.Services.AddIdentityServer()
    .AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options =>
    {
        options.IdentityResources["openid"].UserClaims.Add("role");
        options.ApiResources.Single().UserClaims.Add("role");
    });

After I successfully log in and visit the Test page for configuring authorization:

@page "/Test"
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization

<AuthorizeView Roles="Admin,User,Owner">
    <Authorized>
        <h3>Welcome, authorized user!</h3>
        <p>You have access to this content because you are in one of the following roles: Admin, User, or Owner.</p>
    </Authorized>
    <NotAuthorized>
        <h3>Access Denied</h3>
        <p>You do not have permission to view this content.</p>
    </NotAuthorized>
</AuthorizeView>

@code {
   
}

enter image description here

For more information, you can refer to this document

Reasons:
  • Blacklisted phrase (1): this document
  • Probably link only (1):
  • Long answer (-1):
  • Has code block (-0.5):
Posted by: Yuning Duan