'Where to set custom ClaimsPrincipal for all HttpRequests

I'm porting older application to ASP.NET Core, that uses Windows Authentication (configured in IIS, resp. launchsetting.json).

I would like to override the authentication to use custom hardcoded ClaimsPrincipal, when running in developlement mode.

public class Startup
{
   public void Configure(IApplicationBuilder app, IHostingEnvironment env)
   {

       if (env.IsDevelopment())
       {
           app.UseDeveloperExceptionPage();
       }
       app.UseMvc();    
   }
}

I'm not sure what is the correct place to set the identity and services/middleware configuration to use...



Solution 1:[1]

Create middleware sets HttpContext.User to hardcoded ClaimsPrincipal

public class WindowsUserMiddleware
{
    private readonly RequestDelegate _next;

    public WindowsUserMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext httpContext)
    {
        var claims = new List<Claim> { /* add claims */ };
        var userIdentity = new ClaimsIdentity(claims, "NonEmptyAuthType");

        httpContext.User = new ClaimsPrincipal(userIdentity);

        await _next(httpContext);
    }
}

public static class WindowsUserMiddlewareExtensions
{
    public static IApplicationBuilder UseWindowsUser(this IApplicationBuilder applicationBuilder)
    {
        return applicationBuilder.UseMiddleware<WindowsUserMiddleware>();
    }

}

And use it in development mode only

if (env.IsDevelopment())
{
    app.UseWindowsUser();
    app.UseDeveloperExceptionPage();
}
app.UseMvc();   

Solution 2:[2]

There’s the correct way to edit existing identity and it’s called claims transformation. Basically, we have to write a custom class that implements the IClaimsTransformation interface. Documentation doesn’t give much information about it but the most important thing is said – we need to clone the given identity.

In short, here’s how the process goes:

  1. Clone current user identity

  2. Add custom claims

  3. Return cloned identity

    public class AddRolesClaimsTransformation : IClaimsTransformation
    {
        private readonly IUserService _userService; public class AddRolesClaimsTransformation : IClaimsTransformation
        {
            private readonly IUserService _userService;
    
            public AddRolesClaimsTransformation(IUserService userService)
    {
    
        _userService = userService;
    }
    
    public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
    {
        // Clone current identity
        var clone = principal.Clone();
        var newIdentity = (ClaimsIdentity)clone.Identity;
    
        // Support AD and local accounts
        var nameId = principal.Claims.FirstOrDefault(c => c.Type ==
            ClaimTypes.NameIdentifier || c.Type == ClaimTypes.Name);
        if (nameId == null)
        {
            return principal;
        }
    
        // Get user from database
        var user = await _userService.GetByUserName(nameId.Value);
        if (user == null)
        {
            return principal;
        }
    
        // Add role claims to cloned identity
        foreach (var role in user.Roles)
        {
            var claim = new Claim(newIdentity.RoleClaimType, role.Name);
            newIdentity.AddClaim(claim);
        }
    
        return clone;
    } }
    

The final thing to do is to register claims transformation with dependency injection in the ConfigureServices() method of the Startup class.

services.AddScoped<IClaimsTransformation, AddRolesClaimsTransformation>();
enter code here

Based on https://gunnarpeipman.com/aspnet-core-adding-claims-to-existing-identity/

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Alexander
Solution 2 Vali.Pay