简体   繁体   中英

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. 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.

So after users are authenticated by IIS using Windows Authentication, I plan to read some information and put that among the list of claims:

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.

builder.Services.AddControllers(config =>
{
    config.Filters.Add(new ApiAuthenticationFilter())
});

This method required IFilterMetaData interface, while I have implemented 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 .

Could you please tell me if that's the right approach, or I should try implementing the IActionFilter interface? Or a different approach altogether.

Thanks!

I figured IAuthenticationFilter is not the right approach anymore to add Claims to the ClaimsPrincipal . There's another interface IClaimsTransformation that does exactly what I wanted.

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:

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.

In my Program.cs, I was unable to make it work using the recommended Authentication method:

builder.Services.AddAuthentication(IISDefaults.AuthenticationScheme);

However, using Negotiate worked for me:

builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme).AddNegotiate();

Finally, add our custom IClaimsTranformation implementation to services:

// Claim transformation
builder.Services.AddScoped<IClaimsTransformation, MyClaimsTransformation>();

In the past, it had to be done inside ConfigureServices() method

More details about IClaimsTransformation are available here: https://learn.microsoft.com/en-us/as.net/core/security/authentication/claims?view=as.netcore-6.0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM