Использовать роли авторизации и политики в Blazor WebAssembly с идентификацией? - PullRequest
2 голосов
/ 11 апреля 2020

Я использую приложение Blazor WebAssembly 3.2-preview3, созданное с помощью Identity, которое создало следующие 3 проекта:

App.Client
App.Server
App.Shared

Моя IdentityUser реализация называется AppUser, а моя ApiAuthorizationDbContext реализация называется AppDb

У меня есть роль с именем Admin, назначенная администраторам, и политика с именем RequireAdmin, которая проверяет роль Admin. Однако, когда я пытаюсь использовать AuthorizeView в App.Client и просматривать страницу с администратором, она не показывает ссылку.

<AuthorizeView Policy="RequireAdmin">
    <Authorized>
        <a class="nav-link" href="admin">Admin</a>
    </Authorized>
</AuthorizeView>

Как включить роли и политики в моей Blazor WebAssembly приложение?

1 Ответ

1 голос
/ 11 апреля 2020

1. Создание ролей и политик в App.Shared

Добавьте пакет Microsoft.AspNetCore.Authorization в проект App.Shared

Добавьте следующие 2 класса в App.Shared проект для определения ролей и политик, которые будут использоваться клиентом и сервером.

Shared / RoleTypes.cs

namespace App.Shared
{
    public static class RoleTypes
    {
        public const string Admin = "Admin";
    }
}

Shared / PolicyTypes.cs

using Microsoft.AspNetCore.Authorization;

namespace App.Shared
{
    public static class PolicyTypes
    {
        public const string RequireAdmin = "RequireAdmin";

        public static AuthorizationOptions AddAppPolicies(this AuthorizationOptions options)
        {
            options.AddPolicy(RequireAdmin, policy =>
                policy.RequireRole(RoleTypes.Admin));
            return options;
        }
    }
}

2. Настройте службы в App.Server

Измените файл Startup.cs в проекте App.Server, чтобы добавить политики, вызвав метод расширения, который был только что определен в App.Shared.

* 1031. * Также измените его, чтобы включить требование role в область действия openid.

Server / Startup.cs

using App.Shared;
...

namespace App.Server
{
    public class Startup
    {

        ...

        public void ConfigureServices(IServiceCollection services)
        {
            ...

            services.AddDefaultIdentity<AppUser>(options =>
                {
                    options.SignIn.RequireConfirmedAccount = true;
                })
                .AddRoles<IdentityRole>()
                .AddEntityFrameworkStores<AppDb>();

            services.AddIdentityServer()
                .AddApiAuthorization<AppUser, AppDb>(options =>
                {
                    // https://github.com/dotnet/AspNetCore.Docs/issues/17649
                    options.IdentityResources["openid"].UserClaims.Add("role");
                    options.ApiResources.Single().UserClaims.Add("role");
                });
            // Need to do this as it maps "role" to ClaimTypes.Role and causes issues
            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");

            services.AddAuthentication()
                .AddIdentityServerJwt();

            services.AddAuthorization(options => options.AddAppPolicies());

            ...
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            ...

            app.UseAuthentication();
            app.UseAuthorization();
            app.UseIdentityServer();

            ...
        }
    }
}

3. Настройте службы в App.Client

Измените файл Program.cs в проекте App.Client, чтобы добавить свои политики, вызвав метод расширения, который был только что определен в App.Shared. Также измените AddApiAuthorization для настройки заявки role.

Client / Program.cs

using App.Client.Services;
using App.Shared;
...

namespace App.Client
{
    public class Program
    {
        public static async Task Main(string[] args)
        {
            ...

            builder.Services.AddAuthorizationCore(options => options.AddAppPolicies());
            // 2 calls to AddApiAuthorization are necessary in 3.2-preview3
            // should be fixed in 3.2-preview4
            // https://github.com/dotnet/aspnetcore/issues/19854
            // https://github.com/dotnet/AspNetCore.Docs/issues/17649#issuecomment-612442543
            builder.Services.AddApiAuthorization();
            builder.Services.AddApiAuthorization(options =>
            {
                options.UserOptions.RoleClaim = "role";
            });

            ...
        }
    }
}
...