c# - 带有 Windows 身份验证的 ASP.NET Core 2.1 自定义 RoleProvider
问题描述
我正在将应用程序从 ASP.Net MVC 5 框架迁移到新的 .Net Core 2.1。
我在 MVC 5 项目中使用了带有自定义 RoleProvider 的 Windows 身份验证,如下面的链接所示。
我如何在 Core 2.1 中完成相同的操作,因为它似乎不包含 RoleProvider 功能?
我遇到的每个示例都使用带有 IdentityUser 和 IdentityRole 的个人帐户。
我的用户和角色自定义表:
public class User
{
public User() { UserRoles = new HashSet<UserRole>(); }
[Key]
public string Id { get; set; }
[StringLength(50)]
[Required]
public string Logon { get; set; } //The users Active Directory Username
public bool Active { get; set; }
public ICollection<UserRole> UserRoles { get; set; }
}
public class Role
{
public Role() { UserRoles = new HashSet<UserRole>(); }
[Key]
public string Id { get; set; }
public string Name { get; set; }
public ICollection<UserRole> UserRoles { get; set; }
}
编辑:
我添加了一个 CustomClaimsPrincipal ,如下所示:
public class CustomClaimsPrincipal : ClaimsPrincipal
{
private readonly ApplicationDbContext _context;
public CustomClaimsPrincipal(ApplicationDbContext context)
{
_context = context;
}
public override bool IsInRole(string role)
{
var currentUser = ClaimsPrincipal.Current.Identity.Name;
IdentityUser user = _context.Users.FirstOrDefault(u => u.UserName.Equals(currentUser, StringComparison.CurrentCultureIgnoreCase));
//(ApplicationUser)_context.Users.FirstOrDefault(u => u.UserName.Equals(currentUser, StringComparison.CurrentCultureIgnoreCase));
var roles = from ur in _context.UserRoles.Where(p => p.UserId == user.Id)
from r in _context.Roles
where ur.RoleId == r.Id
select r.Name;
if (user != null)
return roles.Any(r => r.Equals(role, StringComparison.CurrentCultureIgnoreCase));
else
return false;
}
}
并添加到 Startup.cs
services.AddIdentity<ApplicationUser, IdentityRole>().AddEntityFrameworkStores<ApplicationDbContext>();
services.AddScoped<ClaimsPrincipal, CustomClaimsPrincipal>();
但它似乎仍然采用原始的 ClaimsPrincipal IsInRole 函数而不是覆盖,我相信这就是我收到错误消息“主域和受信任域之间的信任关系失败”的原因。
解决方案
我遇到了同样的问题 - 帖子中给出的解决方案没有帮助,但评论指出了我正确的方向。您需要向您的 ClaimsPrincipal 添加声明。
第 1 步:创建 ClaimsTransformer - 替换“Admin”并为您从数据库中获取的每个角色添加单独的声明
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
public class ClaimsTransformer : IClaimsTransformation
{
public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
var ci = (ClaimsIdentity) principal.Identity;
var c = new Claim(ci.RoleClaimType, "Admin");
ci.AddClaim(c);
return Task.FromResult(principal);
}
}
第 2 步:将您的 ClaimsTransformer 添加到 Startup.cs 的 ConfigureServices 方法中
services.AddAuthentication(Microsoft.AspNetCore.Server.IISIntegration.IISDefaults.AuthenticationScheme);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
services.AddSingleton<IClaimsTransformation, ClaimsTransformer>();
第 3 步:您现在可以在控制器中添加基于角色的授权属性
[Authorize(Roles = "Admin")]
[HttpGet("[action]/{id}")]
public User GetUser([FromRoute] int id)
{
UserLogic ul = new UserLogic();
return ul.GetUser(id);
}
推荐阅读
- javascript - 如何在某些索引处删除带有按钮的列表项 HTML 和 JS
- javascript - 这是在 Node.js 中将字符串转换为对象的最佳方法吗?
- php - 如何返回在条件中评估的变量的名称
- c# - 如何使用 Unicode 从字符串中拆分数据?
- android - 在本机中构建失败
- java - Ubuntu中不可解析的父POM
- python - “str”对象在 Python turtle 中没有属性“turtle”
- java - 如何使用 BigDecimal 值进行加法?
- r - R - 如何通过子集条件将数据添加到新列?
- php - GET 返回 https:// 而不是 https://