I have a Blazor Server app that uses Windows Auth. Based on the group memberships of the user, I am adding role claims using IClaimsTransformation. The group-to-role mapping is fetched from a DB.
This is my implementation of IClaimsTransformation:
public class WindowsAuthClaimsTransformation : IClaimsTransformation{ private readonly IDataService _dataService; public WindowsAuthClaimsTransformation(IDataService dataService) { _dataService = dataService; } public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal) { if (!(principal.Identity is ClaimsIdentity)) return principal; var identity = principal.Identity as ClaimsIdentity; if (identity?.IsAuthenticated == false) return principal; var userGroupClaims = identity.FindAll("http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid").ToList(); var groupRoleMappings = await _dataService.GetList<GroupRoleMapping>(); var roles = new List<string>(); foreach (var mapping in groupRoleMappings) { if (userGroupClaims.Any(x => x.Value.TrimEnd() == mapping.GroupSID)) { roles.Add(mapping.RoleName); } } foreach (var role in roles) { identity.AddClaim(new Claim(ClaimTypes.Role, role)); } return principal; }}This is registered as a scoped service in Program.cs:
public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); // add windows auth builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme) .AddNegotiate(); // database interaction logic builder.Services.AddScoped<IDataService, SqlDataService>(); // add claimstransformation builder.Services.AddScoped<IClaimsTransformation, WindowsAuthClaimsTransformation>(); builder.Services.AddAuthorization(options => { // By default, all incoming requests will be authorized according to the default policy. options.FallbackPolicy = options.DefaultPolicy; }); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseAntiforgery(); app.MapRazorComponents<App>() .AddInteractiveServerRenderMode(); app.Run(); } }SamplePage.razor:
<AuthorizeView Roles="Admin" ><Authorized><p>You are an admin. Your roles: @string.Join(", ", @context.User.Claims.Where(c => c.Type == ClaimTypes.Role).Select(c => c.Value))</p><br /></Authorized><NotAuthorized><p>You are not an admin. Your roles: @string.Join(", ", @context.User.Claims.Where(c => c.Type == ClaimTypes.Role).Select(c => c.Value))</p></NotAuthorized></AuthorizeView>This gives me the following text output:
You are not an admin. Your roles: Admin, UserWhich makes me think that my ClaimsTransformation is working properly, however the AuthorizeView is not properly recognizing it.How can I solve this?