我有一个使用 Windows Auth 的 Blazor Server 应用程序。根据用户的组成员身份,我使用 IClaimsTransformation 添加角色声明。组到角色的映射是从数据库中获取的。
这是我的 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;
}
}
这在 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>
这给了我以下文本输出:
You are not an admin. Your roles: Admin, User
这让我认为我的 ClaimsTransformation 工作正常,但是 AuthorizeView 没有正确识别它。 我该如何解决这个问题?
添加如下角色声明即可通过授权:
foreach (var role in roles)
{
identity.AddClaim(new Claim(identity.RoleClaimType, role));
//identity.AddClaim(new Claim(ClaimTypes.Role, role));
}