我正在编写一个blazor网站,它需要允许根据预先存在的SQL数据库中的记录访问某些页面。我一直在研究所需的内容,但大部分都找到了关于.Net Core 1.0的说明,但2.0及以上版本的流程已经改变,我找不到我需要做什么的完整画面。
我的网站使用的是windows认证。我修改了一个页面,内容是这样的。@attribute [Authorize(Roles="Editor")]. 我添加了一个IClaimsTransformation的实现,如下。
public class ClaimsTransformer : IClaimsTransformation {
private readonly Model model;
public ClaimsTransformer(Model model) {
this.model = model;
}
public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal) {
var cp = principal.Clone();
var identity = (ClaimsIdentity)cp.Identity;
var userName = identity.Name;
var usec = await model.ApprovalUsers.SingleOrDefaultAsync(r => EF.Functions.Like(r.Login, userName));
if (usec != null) {
if (usec.IsEditor) identity.AddClaim(new Claim(ClaimTypes.Role, "Editor"));
}
return cp;
}
}
模型是一个EF核心模型 除了Editor claim之外,我暂时去掉了所有的功能,以保持简单。
下面是我的ConfigureServices。
public void ConfigureServices(IServiceCollection services) {
services.AddRazorPages();
services.AddScoped<IClaimsTransformation, ClaimsTransformer>();
services.AddDbContext<Model>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")), ServiceLifetime.Transient);
services.AddBlazoredToast();
services.AddServerSideBlazor();
services.AddAuthorization(opt => {
opt.AddPolicy("Admin", policy => policy.RequireClaim("Admin"));
opt.AddPolicy("Editor", policy => policy.RequireClaim("Editor"));
});
}
而这是我的Configure。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
if (env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
} else {
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.UseAuthentication();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints => {
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
当我导航到带有授权属性的页面时,我得到了一个 "未授权 "的消息,但我的IClaimsTransformation实现从未被调用。我不确定是否需要在ConfigureServices中添加一些东西来向授权系统注册(以及将其注册为范围服务)。我也不相信这是实现我想做的事情的正确方法。
services.AddAuthorization(opt => {
opt.AddPolicy("Admin", policy => policy.RequireClaim("Admin"));
opt.AddPolicy("Editor", policy => policy.RequireClaim("Editor"));
});
谁能告诉我正确的方向?
好吧,看来答案是在ConfigureServices中加入以下一行。
services.AddAuthentication(Microsoft.AspNetCore.Server.IISIntegration.IISDefaults.AuthenticationScheme);
而不是简单地...
services.AddAuthentication();
我想,既然应用程序知道我的windows凭证,那么认证就已经成功了,但我想不是。
另外,策略的东西也不需要--显然是事后诸葛亮,因为我使用的是角色而不是策略。我想当时我已经尝试了太多的组合,以至于我忘记了我想要实现的目标。