我想为aspnet.core创建基于策略的授权
我有很多我想要实现的策略,我不想使用策略来扩展startup.cs文件。
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthorization(options =>
{
options
.AddPolicy("Policy1", policyBuilder =>
{
policyBuilder
.RequireClaim("scope", "1")
.Build();
}).AddPolicy("Policy2", policyBuilder =>
{
policyBuilder
.RequireClaim("scope", "2")
.Build();
}).AddPolicy("Policy3", policyBuilder =>
{
policyBuilder
.RequireClaim("scope", "3")
.Build();
}).AddPolicy("Policy4", policyBuilder =>
{
policyBuilder
.RequireClaim("scope", "4")
.Build();
;
});
});
}
我想在启动时注入所有策略。
有没有人知道如何做到这一点?
我考虑创建一个通过反射获取所有策略的工厂,但我真的希望能够将类注入到策略中。
e.g。
public interface IPolicy
{
string Name { get; }
AuthorizationPolicy AuthorizationPolicy { get; }
}
public class UserCreatePolicy : IPolicy
{
public const string Name = "UserCreatePolicy";
public UserCreatePolicy(IUserRoleService userRoleService)
{
_userRoleService = userRoleService;
}
public AuthorizationPolicy AuthorizationPolicy =>
new AuthorizationPolicyBuilder()
.RequireClaim("scope", _userRoleService.GetRole(1))
.Build();
}
public class AuthorizationPolicyFactory
{
public static void Create(AuthorizationOptions authorizationOptions)
{
typeof(IPolicy).Assembly
.GetTypes()
.Where(x => typeof(IPolicy).IsAssignableFrom(x) && !x.IsAbstract && !x.IsInterface)
.ToList()
.ForEach(type =>
{
if (Activator.CreateInstance(type) is IPolicy policy)
{
authorizationOptions.AddPolicy(policy.Name, policy.AuthorizationPolicy);
}
});
}
}
理想情况下,我不想使用反射,而是使用依赖注入。
答案 0 :(得分:1)
您可以直接使用IServiceProvider
。即使它是这种情况的反模式,我也没有办法解决。
public interface IPolicy
{
string Name { get; }
void ConfigurePolicy(AuthorizationPolicyBuilder builder);
}
public class UserCreatePolicy : IPolicy
{
public string Name { get; } = "UserCreatePolicy";
public UserCreatePolicy(IUserRoleService userRoleService)
{
_userRoleService = userRoleService;
}
public void ConfigurePolicy(AuthorizationPolicyBuilder builder)
{
builder
.RequireClaim("scope", _userRoleService.GetRole(1))
.Build();
}
}
要配置此策略,我已经创建了一个扩展方法。
public static class AuthorizationPolicyExtensions
{
public static void ConfigureAuthorizationPolicies(this IServiceCollection serviceCollection, AuthorizationOptions authorizationOptions)
{
var policiesTypes = typeof(IPolicy).Assembly
.GetTypes()
.Where(x => typeof(IPolicy).IsAssignableFrom(x) && !x.IsAbstract && !x.IsInterface)
.ToList();
foreach (var type in policiesTypes)
{
serviceCollection.AddTransient(type);
}
var serviceProvider = serviceCollection.BuildServiceProvider();
var policies = policiesTypes
.Select(x => serviceProvider.GetService(x) as IPolicy)
.Where(x => x != null);
foreach (var policy in policies)
{
authorizationOptions.AddPolicy(policy.Name, policy.ConfigurePolicy);
}
}
}
它搜索IPolicy
类型并将它们注册到控件容器的反转中。然后,它将使用IPolicy
解析那些IServiceProvider
并注册它们。