我正在通过尝试最小的实现来了解 Blazor 中身份验证的工作原理。通过更改我的虚拟对象AuthenticationStateProvider
以返回具有或不具有身份的索赔委托人,我可以看到它AuthorizeView
在“主页”、“柜台”和“天气”页面上按预期工作。@attribute [Authorize]
在计数器和天气页面上也可以按预期工作,但在主页上则不然。为什么[Authorize]
主页上的行为不同?我需要添加什么才能使其在主页上正常工作?
我从身份验证为“无”的服务器模板以及熟悉的计数器和天气示例页面开始。我添加了一个虚拟对象AuthenticationStateProvider
,如下所示,并将RouteView
in更改Routes.razor
为 an ,AuthorizeRouteView
无需任何其他配置。我怀疑这是需要其他东西的地方。
如果我[Authorize]
在主页上使用,我会收到此错误:
InvalidOperationException:无法找到所需的“IAuthenticationService”服务。请通过在应用程序启动代码中调用“IServiceCollection.AddAuthentication”来添加所有必需的服务。
使用 时AddAuthentication()
,错误发生变化:
InvalidOperationException:未指定authenticationScheme,并且未找到DefaultChallengeScheme。可以使用 AddAuthentication(string defaultScheme) 或 AddAuthentication(Action configureOptions) 设置默认方案。
对于虚拟方案名称,此错误保持不变。
public class DummyAuthStateProvider : AuthenticationStateProvider
{
public override Task<AuthenticationState> GetAuthenticationStateAsync()
{
return Task.FromResult(new AuthenticationState(new ClaimsPrincipal(new DummyIdentity())));
}
private class DummyIdentity : IIdentity
{
public string? AuthenticationType => "dummy";
public bool IsAuthenticated => true;
public string? Name => "dummy";
}
}
builder.Services.AddScoped<AuthenticationStateProvider, DummyAuthStateProvider>();
更新:我尝试AuthenticationHandler
按照答案中的建议添加一个。结果很奇怪。
- 当应用程序启动时,
AuthenticationHandler
和AuthenticationStateProvider
都会被调用。 - 和以前一样,
AuthenticationStateProvider
每个电路仅调用一次或两次,具体取决于是否启用预渲染。 - 被
AuthenticationHandler
调用五次。 - 如果
AuthenticationHandler
返回未经身份验证的用户(即ClaimsPrincipal
不带IIdentity
),则主页只是一个空白页面,而不是[Authorize]
在其他页面上生成的 Blazor“未授权”消息。 - 如果
AuthenticationHandler
返回经过身份验证的用户,但AuthenticationStateProvider
返回未经身份验证的用户,则未经身份验证的用户优先处理 Blazor 的所有内容,包括主页,这将成为标准的“未授权”消息。
我仍然怀疑如果没有一些我尚未发现的额外配置,AuthorizeRouteView
就无法正确处理路由。"/"
[Authorize] 属性需要 builder.Services.AddAuthentication,因此您可以将其保留在 Web 应用程序中。
由于 Microsoft.AspNetCore.Authentication 需要 AuthenticationScheme 的规范,因此您的 program.cs 中应该包含这样的代码:
以下是具有所需 AuthentificationScheme 的 Dummy-Handler 示例:
解释:
AddAuthentication
调用会在构建器的服务集合中注册身份验证服务。ServicesAddScheme
方法来注册您的自定义身份验证方案(“DummyAuthenticationScheme”)DummyAuthenticationHandler
是创建 ClaimsPrinciple 的负责类(在大多数情况下是您的授权用户)当然,这只是一个非常小的实现,但是就您的问题而言,这应该已经有很大帮助了。如果您需要更多帮助,请随时发表评论。