Сбой аутентификации пользовательского `AuthenticationStateProvider`

Я создал пользовательский ApiAuthenticationStateProvider, который после возврата AuthenticationState по-прежнему указывает

info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
      Authorization failed.

Вот упрощенная версия моей ошибки ApiAuthenticationStateProvider:

public class ApiAuthenticationStateProvider : AuthenticationStateProvider
{
   public override Task<AuthenticationState> GetAuthenticationStateAsync()
   {
       Console.WriteLine("Getting auth state...");
               
       var claims = new[] { new Claim(ClaimTypes.Name, "[email protected]") };
       var authenticatedUser = new ClaimsPrincipal(new ClaimsIdentity(claims));
       var authState = Task.FromResult(new AuthenticationState(authenticatedUser));

       return Task.FromResult(authState);
   }
}

Я могу сказать, что Console.WriteLine использует моего пользовательского провайдера, но чтобы предоставить полную информацию, вот код, который я использовал, чтобы добавить это в Program.cs:

builder.Services.AddScoped<AuthenticationStateProvider, ApiAuthenticationStateProvider>();


person weeksdev    schedule 08.07.2020    source источник


Ответы (3)


Проблема может быть решена в этом ответе. https://stackoverflow.com/a/20254797/2682662

В основном при построении ClaimsIdentity вам необходимо указать строковое значение для типа аутентификации.

var authenticatedUser = new ClaimsPrincipal(new ClaimsIdentity(claims, "Needs Auth Type Here"));
person Niederee    schedule 08.07.2020
comment
этот ответ кажется наиболее правильным и ссылается на объяснение того, почему необходима строка «тип аутентификации». - person kltft; 08.07.2020

Чтобы это работало на Blazor, вам нужно будет добавить значение параметра authenticationType с ClaimsIdentity, чтобы ваш код был изменен на:

public class ApiAuthenticationStateProvider : AuthenticationStateProvider
{
   public override Task<AuthenticationState> GetAuthenticationStateAsync()
   {
       Console.WriteLine("Getting auth state...");
               
       var claims = new[] { new Claim(ClaimTypes.Name, "[email protected]") };
       var authenticatedUser = new ClaimsPrincipal(new ClaimsIdentity(claims, AuthenticationTypes.Password));
       var authState = Task.FromResult(new AuthenticationState(authenticatedUser));

       return Task.FromResult(authState);
   }
}

Обратите внимание на параметр AuthenticationTypes.Password для КлаймсИдентити.

Это должно быть одинаковым во всех местах, где строится ClaimsIdentity.

Обновление: согласно этот комментарий, значение типа аутентификации должно быть одним из значений, определенных в AuthenticationTypes class. Обновлен приведенный выше код, чтобы использовать этот класс вместо случайного имени типа аутентификации.

person Umair    schedule 08.07.2020

https://docs.microsoft.com/en-us/dotnet/api/system.security.claims.claimsidentity.-ctor?view=netcore-3.1

ваш объект ClaimsIdentity(), созданный только с массивом утверждений, который вы создали выше, выглядит правильно в документации, но предоставление строки типа утверждения (также в приведенной выше документации) кажется фактически тем, что требуется

var authenticatedUser = new ClaimsPrincipal(new ClaimsIdentity(claims, "Needs Auth Type Here"));

person kltft    schedule 08.07.2020