我需要根据内部部署Active Directory中的一些信息实现自定义授权。在做了一些研究之后,我认为最好的方法是编写一个自定义的身份验证过滤器,并将AD中的信息添加到声明列表中。
因此,在IIS使用Windows身份验证对用户进行身份验证后,我计划阅读一些信息,并将其放在声明列表中:
public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
var claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.Name, userPrincipal.Name));
claims.Add(new Claim(ClaimTypes.Role, "client"));
claims.Add(new Claim("Accounts", "[List of accounts from AD]"));
var identity = new ClaimsIdentity(claims);
var principal = new ClaimsPrincipal(new[] { identity });
context.Principal = principal;
Thread.CurrentPrincipal = context.Principal;
}
我相信这种方法将允许我从任何控制器访问帐户列表。但是,我无法使用以下方法将我的IAuthenticationFilter
实现添加到全局筛选器列表中。
builder.Services.AddControllers(config =>
{
config.Filters.Add(new ApiAuthenticationFilter())
});
这个方法需要IFilterMetaData
接口,而我已经实现了IAuthenticationFilter
。在以前的Web API版本中,我们可以在Application_Start()
方法中访问HttpConfiguration
,但在ASP.NET Core 6 Web API中,我无法找到将筛选器添加到HttpConfiguration
的方法。
你能告诉我这是不是正确的方法,或者我应该尝试实现IActionFilter
接口吗?或者完全不同的方法。
谢谢!
我认为IAuthenticationFilter
不再是向ClaimsPrincipal
添加Claims的正确方法。还有另一个接口IClaimsTransformation
,它正是我想要的。
ASP.NET网站上发布的例子是为ClaimsPrincipal
创建一个新的ClaimsIdentity
实例,而我只需添加到现有的声明列表中就可以实现这一点:
public class MyClaimsTransformation : IClaimsTransformation
{
private readonly IActiveDirectoryService _activeDirectoryService;
public MyClaimsTransformation(IActiveDirectoryService activeDirectoryService)
{
_activeDirectoryService = activeDirectoryService;
}
public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
var identity = principal.Identities.FirstOrDefault(c => c.IsAuthenticated);
if (identity == null)
{
return principal;
}
var user = _activeDirectoryService.GetUser(principal.Identity as WindowsIdentity);
// Add or replace identity.Claims
if (!principal.HasClaim(c => c.Type == MyClaimTypes.ACCOUNTS))
{
identity.AddClaim(new Claim(MyClaimTypes.ACCOUNTS, user.Accounts));
}
return principal;
}
}
使用IClaimsTransformation
的另一个优点是能够通过.Net核心DI容器注入依赖关系。
在我的Program.cs中,我无法使用推荐的身份验证方法:使其工作
builder.Services.AddAuthentication(IISDefaults.AuthenticationScheme);
然而,使用Negotiate对我有效:
builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme).AddNegotiate();
最后,将我们的自定义IClaimsTranformation
实现添加到服务中:
// Claim transformation
builder.Services.AddScoped<IClaimsTransformation, MyClaimsTransformation>();
过去,它必须在ConfigureServices()
方法内完成
有关IClaimsTransformation的更多详细信息,请访问此处:https://learn.microsoft.com/en-us/aspnet/core/security/authentication/claims?view=aspnetcore-6.0
有点晚了,但我已经为您实现了针对MinimalApis和基于Controller-Based API的IClaimsTransformation的完整实现https://github.com/amiru3f/remote-claim-transformation
请注意,ClaimsTransofmer不负责授权/身份验证。它只负责填写您的索赔,您可以确保用户是否有要求的索赔