希望我的问题会很清楚。 ;-) 是否可以在运行时更改中间件设置?我会解释更多。
我在Asp.net core 2.1 webapi的configure services方法中有以下代码
services.AddMvc(options =>
if (!securitySettings)
{
options.Filters.Add(new AllowAnonymousFilter());
}
我想根据数据库中的设置添加该过滤器。可以在运行时更改它,还是在更改设置后真的需要重新启动应用程序?
答案 0 :(得分:0)
不幸的是,您无法在应用程序启动后修改应用于MVC的过滤器。
但是,MVC具有authorization requirements的概念,该概念在每个请求上执行。这使它们成为您想要实现的目标的理想之选。
在更高层次上,我们将:
让我们创建需求类。它是空的,因为它不需要任何参数,因为结果将完全来自数据库:
public class ConditionalAnonymousAccessRequirement : IAuthorizationRequirement
{
}
然后我们创建处理此要求的类:
public class ConditionalAnonymousAccessHandler : AuthorizationHandler<ConditionalAnonymousAccessRequirement>
{
private readonly AppDbContext _context;
public ConditionalAnonymousAccessHandler(AppDbContext context)
{
_context = context;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ConditionalAnonymousAccessRequirement requirement)
{
if (IsAnonymousAccessAllowed())
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
private bool IsAnonymousAccessAllowed()
{
// Implementation based on the value retrieved from the database
}
}
实现很简单。如果我们在数据库中发现允许匿名访问,则将此要求标记为成功。如果一项策略中的至少一项要求得到满足,则整个策略成功。
下一步是将该要求添加到授权策略中。默认情况下,当使用不带参数的[Authorize]
属性时,MVC使用默认的授权策略just checks that the user is authenticated。让我们对其进行修改,以在您的ConfigureServices
类的Startup
方法中添加此新要求:
services.AddAuthorization(options =>
{
options.DefaultPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddRequirements(new ConditionalAnonymousAccessRequirement())
.Build();
});
一切看起来不错,但我们最后缺了一件。
在将需求添加到策略中时,我们尚未注册需求处理程序is necessary for MVC to discover it。再次通过ConfigureServices
方法完成。
services.AddScoped<IAuthorizationHandler, ConditionalAnonymousAccessHandler>();
尽管文档显示处理程序已注册为单例,但在这种情况下,最好按HTTP请求注册处理程序,因为它依赖于DbContext
,默认情况下按HTTP请求注册。将处理程序注册为单例意味着DbContext的实例将在整个应用程序生存期内保持活动状态。
请让我知道你的生活!