'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:
Clone current user identity
Add custom claims
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 |