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

查看:123
本文介绍了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进行依赖注入

推荐答案

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

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既保存数据(在您的情况下为用户名),并执行授权逻辑. 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.

对此的解决方案是将其分为两类-一方面是仅保存与需求相关联的数据的需求,另一方面是授权处理程序.需要注意的是,即使我们会仔细研究,我所描述的内容也可以在

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 class 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天全站免登陆