如何覆盖默认的Windows身份验证ClaimsPrincipal用户和授权控制器方法属性

时间:2016-12-15 06:12:56

标签: asp.net-core asp.net-core-mvc asp.net-core-identity

我有一个有效的ASP.NET核心网站,它使用ASP.NET身份个人用户身份验证,并拥有用户和角色的ASP.NET身份表。

现在有些用户想要使用Windows身份验证而不是用户名/密码。

我可以部署我的网站副本,只需调整web.config并更改aspNetCore标记属性

forwardWindowsAuthToken="false"

forwardWindowsAuthToken="true"

我想为现有的个人用户帐户站点以及Windows身份验证站点使用相同的代码库。

这意味着我将在IIS中拥有两个网站。 我在web.config中部署了一个forwardWindowsAuthToken="false"(个人用户帐户) 和另一个forwardWindowsAuthToken="true"(Windows身份验证)

我有一个属性来扩展ASP.NET Identity个人用户帐户

 public class ApplicationUser : IdentityUser
 {
    [StringLength(50)]
    public string DomainUserName { get; set; }
 }

然后我在数据库中添加了一个唯一的约束

CREATE UNIQUE NONCLUSTERED INDEX AspNetUsers_DomainUserName_Constraint
ON [AspNetUsers](DomainUserName)
WHERE DomainUserName IS NOT NULL;

对于Windows身份验证站点,我需要以某种方式从个人用户帐户标识表加载ClaimsPrincipal用户,或者能够覆盖各个ClaimsPrincipal用户方法和函数以查找现有ASP.Identity表中的角色而不是使用域组作为角色。

我可以使用User.Identity.Name给我我的域名,然后使用它来查询我的aspnetusers表,使用Entity Framework Code First来获取任何用户信息

我需要现有的控制器方法属性(如[Authorize(Roles = "Admin")]方法)在数据库中使用AspNetRoles组而不是域组作为角色,在两个站点中继续以相同的方式工作。

如何覆盖[Authorize(Roles = "Admin")]控制器方法属性以查询数据库,或者通过查询aspnetusers表替换Controller ClaimsPrincipal Windows用户。

或以某种方式替换Windows部署站点的中间件。

我目前的Startup.cs

 services.AddIdentity<ApplicationUser, ApplicationRole>(options =>{})
     .AddEntityFrameworkStores<MyDbContext, Guid>()
     .AddDefaultTokenProviders();

1 个答案:

答案 0 :(得分:0)

我有同样的要求,从我的角度来看,无法正确混合Windows身份验证和个人帐户。

启用Windows身份验证后,该角色必须由Windows / AD组管理。您可以实现 IClaimsTransformation 接口,该接口允许从HTTP请求中截取身份用户,并将其从数据库添加到角色,但这会在我的情况下创建AD检测到的安全漏洞。我不得不使用除角色之外的特定声明来解决问题,因此我根据声明而不是角色授权属性检查策略。

从我的角度来看,管理Windows身份验证和个人帐户身份验证的最佳方法是拥有2个身份验证服务,一个用于Windows,另一个用于个人帐户,每个身份验证服务生成一个令牌(例如JWT),由ressource接受服务。

现在,为了回复您的问题,请实现接口IClaimsTransformation并将其添加到startup.cs文件中:

services.AddSingleton<IClaimsTransformation, MyConcreateClaimsTransformer>();

您可以从IClaimsTransformation类获取ClaimPrincipal并添加从数据库中检索的声明。