У меня есть основное приложение Razorpages ASP.net, выполняющее аутентификацию пользователей Windows через .addNegotiate(). Затем роли назначаются на основе групп AD через преобразователь утверждений, давайте назовем одну из добавленных ролей «Администратор». И дополнительная политика "SiteAuth" была настроена на основе этих ролей.
Авторизация на основе политики "SiteAuth" на странице бритвы с использованием [Authorize(Policy = "SiteAuth")] работает, однако [Authorize(Roles = "Admin")] не работает и перенаправляется на неавторизованную страницу. Упрощение до [Authorize] работает.
Более того, if (User.HasClaim(claim =>claim.Value == "Admin")) также работает как и ожидалось.
Я наблюдал, как преобразование утверждений срабатывает через точку останова при попадании на страницу, показывающую, что пользователь должен быть авторизован и утверждение добавлено.Что я пропустил или сделал не так, что [Authorize(Roles = "Admin")] не авторизуется должным образом?
Longer Tech Подробная версия:
Program.cs – соответствующие части:
Код: Выделить всё
builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
.AddNegotiate();
builder.Services.AddAuthorization(options =>
{
// By default, all incoming requests will be authorized according to the default policy.
options.FallbackPolicy = options.DefaultPolicy;
options.AddPolicy("SiteAuth", policy => policy.RequireAssertion(
context => context.User.HasClaim(claim => claim.Type == ClaimTypes.Role && (new string[] { "SuperAdmin", "Admin", "User" }).Contains(claim.Value))));
});
builder.Services.AddControllers();
builder.Services.AddRazorPages().AddRazorPagesOptions(o =>
{
o.Conventions.ConfigureFilter(new IgnoreAntiforgeryTokenAttribute());
o.Conventions.Add(new ActionRouteConvention());
});
builder.Services.AddMemoryCache();
builder.Services.AddSession();
builder.Services.AddHttpContextAccessor();
builder.Services.AddScoped();
/**** Other Services Added/Configured ***/
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
//app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseSession();
app.UseAuthentication();
app.UseStatusCodePagesWithReExecute("/errors/{0}");
app.UseAuthorization();
app.MapControllers();
app.MapRazorPages();
app.MapGet("/debug-claims", (ClaimsPrincipal user) =>
{
return Results.Ok(user.Claims.Select(c => new { c.Type, c.Value }));
}).RequireAuthorization();
app.Run();
Код: Выделить всё
public class ClaimsTransformer : IClaimsTransformation
{
private readonly SiteSettings _siteSettings;
private readonly IHttpContextAccessor _context;
private readonly ILogger _logger;
public ClaimsTransformer(IHttpContextAccessor httpContextAccessor, SiteSettings siteSettings, ILogger logger)
{
_siteSettings= siteSettings;
_context= httpContextAccessor;
_logger = logger;
}
public Task TransformAsync(ClaimsPrincipal principal)
{
var wi = (WindowsIdentity)principal.Identity;
var ci = (ClaimsIdentity)principal.Identity;
var groups = wi.Groups;
if (groups != null)
{
foreach (var group in groups) //-- Getting all the AD groups that user belongs to---
{
try
{
string groupName = string.Empty;
if(_siteSettings.AdminGroups.TryGetValue(group.Translate(typeof(NTAccount)).ToString(), out groupName))
{
if(!principal.HasClaim(c => c.Value == groupName))
{
//var claim = new Claim("RAAuth", groupName);
//wi.AddClaim(claim);
_logger.LogInformation($"Adding role {groupName} to claims.");
var claim = new Claim(ClaimTypes.Role, groupName);
//wi.AddClaim(claim);
ci.AddClaim(claim);
//claim = new Claim(wi.RoleClaimType, group.Value);
//wi.AddClaim(claim);
}
}
}
catch (Exception ex)
{
throw ex;
}
}
}
return Task.FromResult(principal);
}
}
Сброс утверждений на экран дает:
Код: Выделить всё
{
"type": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
"value": "Admin"
},
{
"type": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
"value": "SuperAdmin"
},
Имя роли было скопировано и вставлено в [Authorize(Roles = "Admin")] , чтобы исключить опечатки
Надеюсь, я напутал здесь что-то простое.
Подробнее здесь: https://stackoverflow.com/questions/786 ... dnegotiate