I have a working ASP.NET Core website which makes of ASP.NET Identity Individual User Authentication and has the ASP.NET Identity tables for Users and Roles.

Now some users want to use Windows Authentication instead of username/password.

I can deploy a copy of my site and just adjust the web.config and change the aspNetCore tag property

forwardWindowsAuthToken="false"

to

forwardWindowsAuthToken="true"

I want to make use of the same codebase for both the existing Individual User Account site as well as the Windows Authentication site.

This means I will have two websites in IIS. I deploy one with forwardWindowsAuthToken="false" (Individual User Account) in the web.config and the other with forwardWindowsAuthToken="true" (Windows Authentication)

I have a property to extend the ASP.NET Identity individual user account

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

I then add in the database a unique constraint on the table

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

For the Windows Authentication site I need to either somehow load the ClaimsPrincipal User from the Individual User Account Identity table or alternatively be able to override the individual ClaimsPrincipal User methods and functions to lookup the Roles in the existing ASP.Identity table instead of using domain groups for roles.

I can use the User.Identity.Name which gives me my domain name and then use it to query my aspnetusers table with Entity Framework Code First to get any User information

I need the existing Controller Method Attributes like [Authorize(Roles = "Admin")] method to continue working the same way in both sites using the AspNetRoles group in the database and not the domain groups as roles.

How do I override the [Authorize(Roles = "Admin")] controller methods attributes to query the database or alternatively replace the Controller ClaimsPrincipal Windows User with my own that I get by querying the aspnetusers table.

Or replace the middleware somehow for the windows deployed site.

My current Startup.cs

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

There are 1 answers

0
Fabrice Jumarie On

I had the same requirement and from my point of view, it not possible to mix Windows authentication and individual account properly.

When Windows authentication is enabled, the role must be managed by Windows/AD group. You can implement IClaimsTransformation interface which allows to intercept identity user from HTTP request and add it the role get from database, but that creates a security breach detected by AD in my case. I had to use specific claims other than role to skirt the problem and so my authorize attribute check policies based on claims and not roles.

From my point of view, the best way to manage windows authentication and individual account authentication is to have 2 authentication services, one for windows and another one for indivual account, each authentication service generates a token (e.g. JWT) accepted by ressource service.

Now, in order to reply to your question, implement the interface IClaimsTransformation and add it in startup.cs file :

services.AddSingleton<IClaimsTransformation, MyConcreateClaimsTransformer>();

You could get ClaimPrincipal from the IClaimsTransformation class and add claims retrieved from database.