我正在开发 ASP.NET Core Web 应用程序 (.NET 5.0)。 这是一个 Intranet 应用程序,因此我使用 Windows 身份验证。 对于授权,我使用 AspNetCore.Identity 中的自定义角色(出于各种原因不想使用 AD 组)。 我正在使用
IClaimsTransformation
类来实现 TransformAsync
方法,以便将我的自定义角色添加到用户的声明中。
我在控制器上添加了 [Authorize(Roles = "Admin")]
来测试整个方案。
当我在调试(IIS Express)中测试时,永远不会调用
TransformAsync
方法。
我确实在我的
launchSettings.json
中检查了 IIS 是否启用了 Windows 身份验证:
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": false,
"iisExpress": {
"applicationUrl": "http://localhost:49861",
"sslPort": 44307
}
我还检查了是否为调试模式启用了 windowsAuthentication (IIS Express): 在此输入图片描述
以下是我的
ConfigureServices
方法(startup.cs
):
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>
(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddControllersWithViews();
// Windows Authentication
services.AddAuthentication(IISDefaults.AuthenticationScheme);
// Claim transformation
services.AddScoped<IClaimsTransformation, AddRolesClaimsTransformation>();
//ASP Identity
services.AddIdentity<ApplicationUser, IdentityRole>().AddEntityFrameworkStores<ApplicationDbContext>();
}
这是我的
Configure
方法(startup.cs
):
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Event}/{action=Dashboard}/{id?}");
});
}
这就是
TransformAsync
方法:
public class AddRolesClaimsTransformation : IClaimsTransformation
{
private readonly UserManager<ApplicationUser> _userManager;
public AddRolesClaimsTransformation(UserManager<ApplicationUser> userManager)
{
_userManager = userManager;
}
public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
//code removed for simplicity - this never gets called
}
}
我尝试按照此
post中的建议更改
services.AddAuthentication(IISDefaults.AuthenticationScheme)
中的顺序startup.cs
,但这并没有解决问题。
我错过了什么?
我终于找到了自己问题的解决方案。 解决方案是在
services.AddAuthentication()
方法 (ConfigureServices
) 中更改对 startup.cs
的调用,如下所示:
之前:
services.AddAuthentication(IISDefaults.AuthenticationScheme);
之后:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = IISDefaults.AuthenticationScheme;
});
这是
ConfigureServices
方法的完整代码(startup.cs
):
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>
(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddControllersWithViews();
//ASP Identity
services.AddIdentity<ApplicationUser, IdentityRole>
().AddEntityFrameworkStores<ApplicationDbContext>();
// Claim transformation
services.AddScoped<IClaimsTransformation, AddRolesClaimsTransformation>();
// Windows Authentication
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = IISDefaults.AuthenticationScheme;
});
}
我知道这是一个较旧的线程。我遇到过同样的问题。我注意到,当调用客户端没有为我的 API 指定任何范围时,IClaimsTransformer 不会被调用。我在服务中添加了一项策略,要求至少声明一个默认范围,现在它按预期工作。
services.AddAuthorization(options => {
List<string> requiredScopes = Configuration.GetSection("RequiredScopes")?.GetChildren().Select(x => x.Value).ToList();
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.RequireScope(requiredScopes)
.Build();
options.AddPolicy("Security Requirements", policy);
});
当您使用身份时,您必须在服务中的身份之后添加此行
services.AddAuthentication(opt => {
opt.DefaultAuthenticateScheme = IISDefaults.AuthenticationScheme;
opt.DefaultChallengeScheme = IISDefaults.AuthenticationScheme;
});
因为身份使用了自己的身份验证
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>
(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddControllersWithViews();
// Claim transformation
services.AddScoped<IClaimsTransformation, AddRolesClaimsTransformation>();
//ASP Identity
services.AddIdentity<ApplicationUser, IdentityRole>().AddEntityFrameworkStores<ApplicationDbContext>();
services.AddAuthentication(opt => {
opt.DefaultAuthenticateScheme = IISDefaults.AuthenticationScheme;
opt.DefaultChallengeScheme = IISDefaults.AuthenticationScheme;
});
}
这个线程可能很旧,但我认为所有答案都无法找出问题,因此并没有真正解决问题。
在 ASP.NET Core 中,仅当满足以下所有条件时才应用
IClaimsTransformation
实例:
IClaimsTransformation
实例已在依赖注入系统中注册,ClaimsPrincipal
已设置(重要,如果您使用自定义身份验证方案)。参考:ASP.NET Core 8 ./src/Http/Authentication.Core/src/AuthenticationService.cs