我有一个ASP.NET Core应用程序,我想在其中添加基于角色的身份验证。我正在使用Windows身份验证,因为它是一个Intranet应用程序。我已经有一个自定义数据库,其中包含坦率地说未映射到IdentityFramework中字段的用户/角色。我可以通过Context.User.Identity.Name轻松获取登录用户的名称。然后,我想在自定义用户/角色表中查找该用户,以获取该用户的可用角色。然后,我想使用在Controller或Action方法级别装饰的基于注释的身份验证筛选器。例如,[Authorize(roles =“ admin”)]。
我能够通过关闭Windows身份验证并使用带有Cookie的表单身份验证来使其正常工作。在AccountController中,我运行了如下代码:
List
然后我将声明存储在cookie中。然后,当我使用[Authorize(roles =“ admin”)]装饰Controller时,便可以毫无问题地检索视图。授权有效。我想在不登录用户的情况下为WindowsAuthentication复制相同的功能。我尝试使用ClaimsTransformer并实现有效的基于策略的授权。但是,如果我用[Authorize(roles =“ admin”)]装饰它,当我导航到操作方法时它会炸弹。这是ClaimsTransformer:
using(LDAPConnection connection = new LDAPConnection(loginModel.UserName,loginModel.Password))
{
List<Claim> claims = new List<Claim> {
new Claim(ClaimTypes.Name, loginModel.UserName),
new Claim(ClaimTypes.Role, "admin")
};
ClaimsIdentity userIdentity = new ClaimsIdentity(claims,"login");
ClaimsPrincipal principal = new ClaimsPrincipal(userIdentity);
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(principal),
new AuthenticationProperties
{
IsPersistent = true,
ExpiresUtc = DateTime.Now.AddDays(200)
});
return Redirect("/");
}
为了使用[Authorize(Roles =“ admin”)],我缺少了哪一部分?顺便说一句,我目前正在使用ASP.NET Core 2.2。
答案 0 :(得分:1)
您可以编写自定义策略授权处理程序,在其中获得所有用户角色,并检查它们是否包含所需的角色名称。
请参阅以下步骤:
1。创建CheckUserRoleRequirement(接受参数)
public class CheckUserRoleRequirement: IAuthorizationRequirement
{
public string RoleName { get; private set; }
public CheckUserRoleRequirement(string roleName)
{
RoleName = roleName;
}
}
2。创建CheckUserRoleHandler
public class CheckUserRoleHandler : AuthorizationHandler<CheckUserRoleRequirement>
{
private readonly IServiceProvider _serviceProvider;
public CheckUserRoleHandler(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
CheckUserRoleRequirement requirement)
{
var name = context.User.Identity.Name;
using (var scope = _serviceProvider.CreateScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService<YourDbContext>();
//your logic to look up the user in the custom user/roles table in order to get the available roles for that user
List<string> roles = dbContext.UserRoles.Where(...;
if (roles != null && roles.Contains(requirement.RoleName))
{
context.Succeed(requirement);
}
}
return Task.CompletedTask;
}
}
3.ConfigureServices中的注册处理程序
services.AddAuthorization(options =>
{
options.AddPolicy("AdminRole", policy =>
policy.Requirements.Add(new CheckUserRoleRequirement("Admin")));
});
services.AddSingleton<IAuthorizationHandler, CheckUserRoleHandler>();
4。用法
[Authorize(Policy = "AdminRole")]
答案 1 :(得分:1)
我知道这有点晚了,但我今天一直在解决同一问题,我在类似帖子中看到的答案都没有解决我的问题。
以下是我通过 Windows 身份验证在控制器上使用 [Authorize(Roles = "Admin")] 所采取的步骤。
UseAuthentication()
方法中仔细检查 UseAuthorization()
是否位于 Configure()
之前 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication(); // <--- this needs to be before
app.UseAuthorization(); // <----this
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Hccc}/{action=Index}/");
});
}
public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
var ci = (ClaimsIdentity)principal.Identity;
var user = UserAuth.GetUserRole(ci.Name); // gets my user from db with role
// handle your roles however you need.
foreach(var role in user.Roles)
{
var roleClaim = new Claim(ci.RoleClaimType, role.RoleName);
ci.AddClaim(roleClaim);
}
return Task.FromResult(principal);
}
ConfigureServices()
方法来处理授权 services.AddSingleton<IClaimsTransformation, ClaimsTransformer>();
// Implement a policy called "AdminOnly" that uses "Windows" authentication
// The policy requires Role "Admin"
services.AddAuthorization(options =>
{
options.AddPolicy("AdminOnly", policy =>
{
policy.AddAuthenticationSchemes("Windows");
policy.RequireRole("Admin");
});
});
services.AddMvc();
services.AddControllersWithViews();
[Authorize]
标签实施政策。就我而言,我想阻止对控制器的访问,除非用户是“管理员”。 [Authorize(Policy = "AdminOnly")]
public class UsersController : Controller
{
}