Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
427 views
in Technique[技术] by (71.8m points)

c# - 对授权策略的依赖注入(Dependency Injection on Authorization Policy)

I want to create a claim based authorization for my ASP.NET Core app:

(我想为我的ASP.NET Core应用创建基于声明的授权:)

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthorization(options =>
    {
        options.AddPolicy("Founders", policy =>
                          policy.RequireClaim("EmployeeNumber", "1", "2", "3", "4", "5"));
    });
}

The problem is that I have a non trivial method to resolve the employee numbers (1 to 5) and I want to use a DI service:

(问题是我有一种非平凡的方法来解析员工人数(1到5),并且我想使用DI服务:)

public interface IEmployeeProvider {

  string[] GetAuthorizedEmployeeIds();
}

I would like to inject this service and use it in AddPolicy, something like:

(我想注入此服务并在AddPolicy中使用它,例如:)

services.AddAuthorization(options =>
{
    options.AddPolicy("Founders", policy =>
              policy.RequireClaim("EmployeeNumber", *employeeProvider.GetAuthorizedEmployeeIds()));
});

Note

(注意)

I know that I can write my own AuthorizationHandler where I can easily inject IEmployeeProvider but I'm against this pattern because:

(我知道我可以编写自己的AuthorizationHandler,在其中可以轻松注入IEmployeeProvider但是我反对这种模式,因为:)

  1. There is a already a handler that does exactly what I need

    (已经有一个处理程序可以完全满足我的需要)

  2. I need to write a new handler for each claim type and each different requirement

    (我需要为每个索赔类型和每个不同的需求编写一个新的处理程序)

  3. This is an anti pattern because the employee ids should really be part of the requirement while the handler should be generic component that handles the requirements

    (这是一种反模式,因为员工id实际上应该是需求的一部分,而处理程序应该是处理需求的通用组件)

So I'm looking for a way to inject services when the policy is being built

(所以我正在寻找一种在构建策略时注入服务的方法)

  ask by Michael Shterenberg translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Thanks to Nkosi for the tip!

(感谢Nkosi的小费!)

Since AddAuthorization is basically configuring AuthorizationOptions behind the scenes, I followed the same pattern only I used OptionsBuilder to configure options with dependencies

(因为AddAuthorization基本上是在幕后配置AuthorizationOptions ,所以我遵循相同的模式,只是我使用OptionsBuilder来配置具有依赖项的选项)

I created my own AddAuthorization method that accepts dependencies:

(我创建了自己的AddAuthorization方法,该方法接受依赖项:)

 public static IServiceCollection AddAuthorization<TDep>(
     this IServiceCollection services,
     Action<AuthorizationOptions, TDep> configure) where TDep : class
 {
     services.AddOptions<AuthorizationOptions>().Configure<TDep>(configure);
     return services.AddAuthorization();
 }

And now I can use it to properly configure the requirement:

(现在,我可以使用它来正确配置需求:)

services.AddAuthorization<IEmployeeProvider>((options, employeeProvider> =>
{
    options.AddPolicy("Founders", policy =>
        policy.RequireClaim("EmployeeNumber", employeeProvider.GetAuthorizedEmployeeIds())
    );
});

You can follow the same technique if you need more dependencies ( OptionsBuilder.Configure supports up to 5 dependencies)

(如果需要更多的依赖项,则可以采用相同的技术( OptionsBuilder.Configure最多支持5个依赖项))

Obviously, this solution requires extra validation when upgrading to newer ASP versions, as the underlying implementation of AddAuhtorization may change

(显然,此解决方案在升级到较新的ASP版本时需要额外的验证,因为AddAuhtorization的基础实现可能会更改)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...