我是第一次使用 Identity。我正在关注 Microsoft 的 Policy-based authorization tutorial,但是当我添加策略和要求时,永远不会调用该要求的处理程序。事实上,它就像永远不会从 DI 检索处理程序一样(如果我注释掉将处理程序添加到 DI 容器的行,应用程序的执行根本不会改变)。
NotLoggedInHandler
旨在确保某些页面只能由未登录的用户访问。处理程序仅成功并返回,因此要求应始终通过:
public class NotLoggedInHandler : AuthorizationHandler<NotLoggedInRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, NotLoggedInRequirement requirement)
{
context.Succeed(requirement);
return Task.CompletedTask;
}
}
但是当我访问受保护的 Razor 页面时,我在日志输出中得到了这个:
[xx:xx:xx INF] Authorization failed. These requirements were not met: WebApp.Policies.NotLoggedInRequirement
我已经处理了添加服务的顺序。 NotLoggedInHandler
是在 services.AddAuthorization
之前还是之后注册似乎无关紧要。
我的 Startup.cs
文件如下所示:
public class Startup
{
// Other methods/ctor omitted
public void ConfigureServices(IServiceCollection services)
{
// Identity services omitted
// Set up Authentication
services.AddAuthentication(...);
// Set up Authorization
services.AddAuthorization(
options =>
{
options.AddPolicy(
"RequireAnonymous",
policy =>
{
policy.Requirements.Add(new NotLoggedInRequirement());
}
);
}
);
services.AddTransient<AuthorizationHandler<NotLoggedInRequirement>, NotLoggedInHandler>();
// Other services omitted, not related to Identity/auth
}
}
答案 0 :(得分:0)
事实证明,我是在做假设,只是需要退一步。如 tutorial from Microsoft 中所述,处理程序是针对 IAuthorizationHandler
接口注册的。
本教程展示了如何创建单个需求的处理程序和多个需求的处理程序,但只明确展示了如何注册多个需求的处理程序。教程中没有明确说明该过程是相同的,并且根据我使用 ASP.NET DI 容器的经验,我认为我的解决方案是有意义的(因为一对一处理程序实现了 IAuthorizationHandler<TRequirement>
,但是一对多处理程序实现 IAuthorizationHandler
).
然而,无论如何都是一样的。我不确定 ASP.NET 如何解决这些依赖项,因为任意数量的处理程序都将注册到 IAuthorizationHandler
接口,但无论如何它都可以工作。
改变这一点:
services.AddTransient<AuthorizationHandler<NotLoggedInRequirement>, NotLoggedInHandler>();
为此:
services.AddTransient<IAuthorizationHandler, NotLoggedInHandler>();
有效地解决了问题。