【问题标题】:.net core 2.0 change injected middleware settings at runtime.net core 2.0 在运行时更改注入的中间件设置
【发布时间】:2019-03-31 04:24:24
【问题描述】:

希望我的问题很清楚。 ;-) 是否可以在运行时更改中间件设置?我解释更多。

我在 Asp.net core 2.1 webapi 的配置服务方法中有以下代码

services.AddMvc(options =>
                if (!securitySettings)
                {
                  options.Filters.Add(new AllowAnonymousFilter());
                }

我想根据数据库中的设置添加该过滤器。是否可以在运行时更改它,还是在更改该设置后我真的需要重新启动我的应用程序?

【问题讨论】:

  • 您是否尝试过编写自己的 MiddlewareFilter 来执行您的自定义逻辑?

标签: dependency-injection asp.net-core-mvc asp.net-core-2.1


【解决方案1】:

很遗憾,在应用程序启动后,您无法修改应用于 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。让我们修改它以在 Startup 类的 ConfigureServices 方法中添加这个新要求:

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 请求注册它,因为它依赖于默认情况下按 HTTP 请求注册的 DbContext。将处理程序注册为单例意味着 DbContext 的实例将在整个应用程序生命周期内保持活动状态。

请告诉我你的进展如何!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-19
    • 2019-03-23
    • 2017-12-30
    • 1970-01-01
    • 1970-01-01
    • 2018-03-08
    • 2018-02-18
    相关资源
    最近更新 更多