DotNet Core 中 AuthorizationOptions 要求的依赖注入 [英] Dependency Injection on AuthorizationOptions Requirement in DotNet Core

查看:21
本文介绍了DotNet Core 中 AuthorizationOptions 要求的依赖注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 .NET 核心项目,正在尝试使用 AuthorizationOptions 创建自定义策略,如位于此处的文档所示:

I have a .NET core project and am trying to create a custom policy using AuthorizationOptions as shown in the documentation located here:

ASP.NET.Core 授权 - 需求处理程序中的依赖注入

示例显示了使用 1 个参数设置授权要求 - 一个简单的 int 值.我的自定义要求需要一个字符串参数和一个 DbContext 对象.我想在运行时将 DbContext 注入到需求的构造函数中.我正在使用 Autofac 容器.我不确定如何实现这一点 - 已经尝试了多种方法,但到目前为止没有任何效果.

The examples show setting up an authorization requirement with 1 parameter - a simple int value. My custom requirement requires a string parameter as well as a DbContext object. I want to inject the DbContext into the requirement's constructor at runtime. I am using the Autofac container. I'm not sure how I can achieve this - have tried several approaches and nothing is working so far.

这是我的自定义要求:

public UserNameRequirement(string username, MyDbContext context)
{
    _userName = username;
    _dbContext = context;
}

在 Startup.cs ConfigureServices 方法中设置授权选项时,文档显示您像这样注册:

When setting up the authorization options in Startup.cs ConfigureServices method the documentation shows you register this like so:

services.AddAuthorization(options =>
{
    options.AddPolicy(
        "UserNamePolicy",
        policy => policy.Requirements.Add(new UserNameRequirement("admin", ** want to resolve and inject my DbContext here **)));
}

我不确定如何实现这一目标.我看过这篇文章,它是一个类似的问题,但它使用的是 ASP.NET 5 并且该语法不适用于 .net 核心:

I am not sure how to achieve this. I've seen this post which is a similar question but it's using ASP.NET 5 and that syntax doesn't work with .net core:

AuthorizationOptions 的依赖注入

推荐答案

好的,我在这里做一个假设,那就是你需要在MyDbContext中注入一个MyDbContext的实例code>UserNameRequirement 来执行业务逻辑.

OK, I'm going to make an assumption here, and that is that you need to inject an instance of MyDbContext in UserNameRequirement to perform the business logic.

如果是这种情况,则意味着 UserNameRequirement 既保存数据 - 在您的情况下为用户名 - 并执行授权逻辑.在 ASP.NET Core 中的一个例子是 ClaimsAuthorizationRequirement.

If this is the case, then it means UserNameRequirement both holds the data - in your case the username - and does the authorization logic. An example of this in ASP.NET Core is the ClaimsAuthorizationRequirement.

对此的解决方案是将其分为两个类 - 一方面是仅保存与需求相关联的数据的需求,另一方面是授权处理程序.请注意,即使我们会通过它,我所描述的内容也可以在 官方 ASP.NET Core 文档.

The solution to this is to separate this into two classes - on one side the requirement that just holds the data associated with the requirement, on on the other side the authorization handler. As a note, even if we'll go through it, what I'm describing is available in the official ASP.NET Core docs.

所以需求类可能看起来像:

So the requirement class could look something like:

public class UserNameRequirement : IAuthorizationRequirement
{
    public UserNameRequirement(string userName)
    {
        UserName = userName;
    }

    public string UserName { get; }
}

并且处理程序类将是:

public class UserNameRequirementHandler : AuthorizationHandler<UserNameRequirement>
{
    private readonly MyDbContext _dbContext;

    public UserNameRequirementHandler(MyDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, UserNameRequirement requirement)
    {
        var userName = requirement.UserName;

        // Use _dbContext to perform business logic
    }
}

接下来也是最后一部分是在容器中注册处理程序:

The next and last part is to register the handler in the container:

services.AddSingleton<IAuthorizationHandler, UserNameRequirementHandler>();

这样做的效果是,您现在可以将您的要求添加到策略中,而无需担心 DbContext:

The effect of doing this is that you can now add your requirement to the policy without worrying about the DbContext:

services.AddAuthorization(options =>
{
    options.AddPolicy(
        "UserNamePolicy",
        policy => policy.Requirements.Add(new UserNameRequirement("admin")));
}

在内部,ASP.NET 将通过容器解析与该需求关联的所有处理程序,因此您可以在处理程序中使用 MyDbContext 的实例,允许您执行业务逻辑你觉得合适.

Internally, ASP.NET will then resolve all the handlers associated with that requirement through the container, so the instance of MyDbContext will be available to you in the handler, allowing you to perform the business logic as you see fit.

希望我的假设是正确的,这对您有所帮助.

Hopefully, my assumption is correct, and this helps you.

Henry Roux 在下面的评论中提出了一个很好的观点,即如果 UserNameRequirementHandler 注册为单例,则将使用 MyDbContext 的单个实例,这可能会导致问题.确保在适当的生命周期中注册授权处理程序.

Henry Roux made a good point in a comment below regarding the fact that if the UserNameRequirementHandler is registered as a singleton, then a single instance of MyDbContext will be used, and that could lead to issues. Make sure you register your authorization handlers with the appropriate lifecycle.

这篇关于DotNet Core 中 AuthorizationOptions 要求的依赖注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆