Авторизация Blazor WASM не работает с ролями AAD

Я пытаюсь настроить авторизацию AAD на основе определенных пользователем ролей, следуя этому документу https://docs.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/azure-active-directory-groups-and-roles?view=aspnetcore-3.1#определяемыепользователемроли Я могу настроить его в манифесте приложения и получить авторизацию API. Однако, когда я пытаюсь сделать это на стороне пользовательского интерфейса, я не могу получить претензию. Я сделал классы интерпретации json (DirectoryObjects, CustomUserAccount и Value (используется объектом каталога)). Я также добавил CustomUserFactory, удалив групповой материал, поскольку меня интересуют только роли:

        private readonly ILogger<CustomUserFactory> _logger;
        private readonly IHttpClientFactory _clientFactory;

        public CustomUserFactory(IAccessTokenProviderAccessor accessor,
            IHttpClientFactory clientFactory,
            ILogger<CustomUserFactory> logger)
            : base(accessor)
        {
            _clientFactory = clientFactory;
            _logger = logger;
        }

        public async override ValueTask<ClaimsPrincipal> CreateUserAsync(
            CustomUserAccount account,
            RemoteAuthenticationUserOptions options)
        {
            var initialUser = await base.CreateUserAsync(account, options);

            if (initialUser.Identity.IsAuthenticated)
            {
                var userIdentity = (ClaimsIdentity)initialUser.Identity;

                foreach (var role in account.Roles)
                {
                    userIdentity.AddClaim(new Claim("role", role));
                }

                
            }

            return initialUser;
        }

а затем я изменил program.cs, как упоминалось в документе:

    builder.Services.AddMsalAuthentication<RemoteAuthenticationState,
    CustomUserAccount>(options =>
    {
        builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
        options.ProviderOptions.DefaultAccessTokenScopes.Add("apiaccessguid");
        options.UserOptions.RoleClaim = "role";
    }).AddAccountClaimsPrincipalFactory<RemoteAuthenticationState, CustomUserAccount,
    CustomUserFactory>();

когда это не сработало, я попытался добавить его как политику, но тоже безуспешно:

 builder.Services.AddAuthorizationCore(options =>
    {
        options.AddPolicy("Admin", policy =>
            policy.RequireClaim("role", "admin"));
    });

для ограничения представления я пробовал в коде с user.IsInRole("admin") и в пользовательском интерфейсе с

<AuthorizeView Roles="admin">
    <li class="nav-item px-3">
        <NavLink class="nav-link" href="Admin">
            Admin
        </NavLink>
    </li>
</AuthorizeView>

и с политикой:

<AuthorizeView Policy="Admin">
    <Authorized>
        <p>
            The user is in the 'Administrator' AAD Administrative Role
            and can see this content.
        </p>
    </Authorized>
    <NotAuthorized>
        <p>
            The user is NOT in the 'Administrator' role and sees this
            content.
        </p>
    </NotAuthorized>
</AuthorizeView>

и ни один из них не работал. Что-то мне не хватает? Я также подтвердил, что токен имеет роль администратора.


person Tacot    schedule 19.08.2020    source источник
comment
Разве вы не упустили роль? документация утверждает, что аутентифицированные пользователи получат назначенные им роли в заявлении roles.   -  person Loul G.    schedule 13.09.2020
comment
Я пробовал это безуспешно, я думаю, что роль правильная, так как в конце CustomUserFactory я делаю цикл ролей и добавляю его с требованием роли, что и сказано в этой документации docs.microsoft.com/en-us/aspnet/core/blazor/security/   -  person Tacot    schedule 14.09.2020


Ответы (2)


Я заставил его работать, используя RequireRole в параметрах политики.

Например, я добавил в манифест роль приложения:

"appRoles": [
    {
        "allowedMemberTypes": [
            "User"
        ],
        "description": "Reader role.",
        "displayName": "Reader",
        "id": "41d9ba42-456e-4471-8946-24216e5f6c64",
        "isEnabled": true,
        "lang": null,
        "origin": "Application",
        "value": "Reader"
    }
]

Настройте политику через RequireRole:

builder.Services.AddAuthorizationCore(options =>
{
    options.AddPolicy("app-reader", policy => policy.RequireRole("Reader"));
});

А затем используйте согласно:

<AuthorizeView Policy="app-reader">
    <Authorized>
        <p>
            The user is in the 'Reader' Role
            and can see this content.
        </p>
    </Authorized>
    <NotAuthorized>
        <p>
            The user is NOT in the 'Reader' role 
            and sees this content.
        </p>
    </NotAuthorized>
</AuthorizeView>

Или как атрибут на бритвенной странице:

@attribute [Authorize(Policy = "app-reader")]
person fuzzy_logic    schedule 17.09.2020

Обнаружил мою проблему, код был в порядке, проблема была на стороне регистрации Azure. Клиент использует роли, зарегистрированные в клиентском приложении в Azure, в то время как сервер использует роли в серверном приложении. поэтому убедитесь, что вы зарегистрировали пользователя в обоих с одной и той же ролью.

person Tacot    schedule 17.09.2020