[英]Custom IAuthenticationFilter in ASP.NET Core 6 Web API based on Active Directory
I need to implement custom authorization based on some information in on-premise Active Directory.我需要根据本地 Active Directory 中的一些信息实施自定义授权。 After doing some research, I figured that best approach would be to write a custom Authentication Filter and add that information from AD to the list of claims.在做了一些研究之后,我认为最好的方法是编写一个自定义身份验证过滤器并将该信息从 AD 添加到声明列表中。
So after users are authenticated by IIS using Windows Authentication, I plan to read some information and put that among the list of claims:因此,在用户通过 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;
}
I believe that this approach will allow me to access the list of accounts from any controller. However, I am unable to add my IAuthenticationFilter
implementation to the list of global filters using the following approach.我相信这种方法将允许我从任何 controller 访问帐户列表。但是,我无法使用以下方法将我的IAuthenticationFilter
实现添加到全局过滤器列表中。
builder.Services.AddControllers(config =>
{
config.Filters.Add(new ApiAuthenticationFilter())
});
This method required IFilterMetaData
interface, while I have implemented IAuthenticationFilter
.此方法需要IFilterMetaData
接口,而我已经实现了IAuthenticationFilter
。 In previous Web API versions, we were able to access HttpConfiguration
in Application_Start()
method, but in ASP.NET Core 6 Web API, I am unable to find a way to add my filter to HttpConfiguration
.在以前的 Web API 版本中,我们能够在Application_Start()
方法中访问HttpConfiguration
,但在 ASP.NET Core 6 Web API 中,我无法找到将过滤器添加到HttpConfiguration
的方法。
Could you please tell me if that's the right approach, or I should try implementing the IActionFilter
interface?你能告诉我这是否是正确的方法,或者我应该尝试实现IActionFilter
接口吗? Or a different approach altogether.或者完全不同的方法。
Thanks!谢谢!
I figured IAuthenticationFilter
is not the right approach anymore to add Claims to the ClaimsPrincipal
.我认为IAuthenticationFilter
不再是将 Claims 添加到ClaimsPrincipal
的正确方法。 There's another interface IClaimsTransformation
that does exactly what I wanted.还有另一个接口IClaimsTransformation
完全符合我的要求。
The example posted on ASP.NET website was creating a new ClaimsIdentity
instance to the ClaimsPrincipal
while I was able to achieve that by just adding to existing list of claims:发布在 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;
}
}
Another advantage of using IClaimsTransformation
is to be able to inject dependencies through.Net core DI container.使用IClaimsTransformation
的另一个好处是可以通过 .Net 核心 DI 容器注入依赖项。
In my Program.cs, I was unable to make it work using the recommended Authentication method:在我的 Program.cs 中,我无法使用推荐的身份验证方法使其工作:
builder.Services.AddAuthentication(IISDefaults.AuthenticationScheme);
However, using Negotiate worked for me:但是,使用 Negotiate 对我有用:
builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme).AddNegotiate();
Finally, add our custom IClaimsTranformation
implementation to services:最后,将我们自定义的IClaimsTranformation
实现添加到服务中:
// Claim transformation
builder.Services.AddScoped<IClaimsTransformation, MyClaimsTransformation>();
In the past, it had to be done inside ConfigureServices()
method过去,它必须在ConfigureServices()
方法中完成
More details about IClaimsTransformation are available here: https://learn.microsoft.com/en-us/as.net/core/security/authentication/claims?view=as.netcore-6.0有关 IClaimsTransformation 的更多详细信息,请访问: https://learn.microsoft.com/en-us/as.net/core/security/authentication/claims?view=as.netcore-6.0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.