已编辑
这适用于 IIS,但不适用于 IISExpress:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddSingleton<IAuthorizationHandler, CheckAdGroupHandler>();
builder.Services.AddAuthentication(IISDefaults.AuthenticationScheme);
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("my_policy", policy =>
{
policy.Requirements.Add(new CheckAdGroupRequirement("some_ad_group, another_ad_group"));
policy.AuthenticationSchemes = new List<string>()
{
IISDefaults.AuthenticationScheme
};
});
});
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.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
CheckAdGroupHandler 所在位置:
public class CheckAdGroupHandler: AuthorizationHandler<CheckAdGroupRequirement>
{
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context,
CheckAdGroupRequirement requirement)
{
List<string> usersGroups = new List<string>();
WindowsIdentity windowsIdentity = (WindowsIdentity) context.User.Identity;
using (var ctx = new PrincipalContext(ContextType.Domain))
using (var user = UserPrincipal.FindByIdentity(ctx, windowsIdentity.Name))
{
if (user != null)
{
foreach (Principal principal in user.GetGroups())
{
string adGroup = principal.SamAccountName;
usersGroups.Add(adGroup);
}
}
}
foreach (var groupName in requirement.GroupNames)
{
if (usersGroups.Contains(groupName))
{
context.Succeed(requirement);
}
}
await Task.CompletedTask;
}
}
并检查广告组要求:
public class CheckAdGroupRequirement:IAuthorizationRequirement
{
public List<string> GroupNames { get; set; }
public CheckAdGroupRequirement(string groupNames)
{
GroupNames = groupNames.Split(',').ToList();
}
}
然后这样装饰index.cshtml.cs:
[Authorize(Policy = "my_policy")]
public class IndexModel : PageModel
{
我的launchSettings.json:
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": false,
"iisExpress": {
"applicationUrl": "http://localhost:64205",
"sslPort": 44374
}
}
但是从 vs2022 本地运行时仍然出现以下错误:
InvalidOperationException: No authentication handlers are registered. Did you forget to call AddAuthentication().Add[SomeAuthHandler]("Windows",...)?
我也尝试过编辑applicationhost.config,但均无济于事。有其他人经历过这个/知道解决办法吗?
在代码中设置“windowsAuthentication”:true或启用iis windows身份验证并禁用其他身份验证。
确保您已设置 program.cs 文件来处理身份验证:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddSingleton<IAuthorizationHandler, CheckAdGroupHandler>();
builder.Services.AddAuthentication(IISDefaults.AuthenticationScheme);
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("my_policy", policy =>
{
policy.Requirements.Add(new CheckAdGroupRequirement("some ad group,another ad group"));
policy.AuthenticationSchemes = new List<string> { IISDefaults.AuthenticationScheme };
});
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.Run();