自定义“AuthenticationStateProvider”身份验证失败

Custom `AuthenticationStateProvider` Authentication Failing

我创建了一个自定义 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, "some.email@somewhere.com") };
       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>();

这个问题可以在这个答案中得到解决。

基本上,在构造 ClaimsIdentity 时,您需要为身份验证类型提供一个字符串值。

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

要在 Blazor 上运行,您必须添加 authenticationType 参数值和 ClaimsIdentity,这样您的代码将更改为:

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

       return Task.FromResult(authState);
   }
}

注意 ClaimsIdentityAuthenticationTypes.Password 参数。

这在所有构建ClaimsIdentity的地方应该是相同的。

更新: 根据 this comment, the value of authentication type should be one of the values defined in AuthenticationTypes class更新了上面的代码以使用此 class 而不是随机身份验证类型名称。

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"));