Here is what I am trying to accomplish , and maybe the mix and match isn't working, but I have had a hard time finding a way to execute the following:
Windows Authentication (AddNegotiate) on an API. After the user is authenticated this way I am retrieving their domain security groups, and then from a dictionary assigning them Role claims based on membership.
I want to be able to share this authenticated session across several other apps that use the API to authenticate, so that the groups query only has to happen once a session times out.
Do I want to do some kind of Cookie implementation to accomplish this? So an application looks, doesn't have authentication, goes to the API where after confirming Windows Groups and Roles issues a cookie based on that membership.
Would probably also have a manual LDAP login elsewhere in the application to Add claims to the current User Identity.
My authentication services. Combination of Cookies and Negotiate, without the NegotateiDefualts on DefaultAuthenticationScheme it prompts a login, and I want that to be an automatic. But then after cookie is set, Cookie should be the authentication.
// Authentication Services services.AddHttpContextAccessor(); services.AddScoped<IUserPreferencesService, UserPreferencesService>(); services.AddScoped<IDomainUserGroupService, DomainUserGroupService>(); services.AddDataProtection() .PersistKeysToFileSystem(new DirectoryInfo(Path.Combine(Directory.GetCurrentDirectory(), "DataProtectionKeys"))) .SetApplicationName("AuthenticationAPI") .SetDefaultKeyLifetime(TimeSpan.FromDays(90)); services.AddAuthentication(options => { options.DefaultAuthenticateScheme = NegotiateDefaults.AuthenticationScheme; options.DefaultChallengeScheme = NegotiateDefaults.AuthenticationScheme; options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; }) .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options => { options.Cookie.Name = "AuthCookie"; options.Cookie.Domain = config["DomainSite"]; options.Cookie.HttpOnly = true; options.Cookie.SecurePolicy = CookieSecurePolicy.Always; options.Cookie.SameSite = SameSiteMode.None; options.Cookie.Path = "/"; }) .AddNegotiate(); // For Windows Authentication to retrieve User GroupsThe /login is a controller:
// LoginUser with Sign In of Claims based on Role Membership [System.Runtime.Versioning.SupportedOSPlatform("windows")] [HttpGet("login")] public async Task<IActionResult> Login() { _logger.LogMessage("Loaded Environment : " + _appConfiguration.EnvrionmentLoaded); if (User.Identity is WindowsIdentity windowsIdentity) { var lastAuthenticated = DateTime.UtcNow; var roles = GetRolesFromGroups(windowsIdentity); var claims = CreateClaims(windowsIdentity.Name, roles, lastAuthenticated); var identity = new ClaimsIdentity(claims, "Cookie"); var principal = new ClaimsPrincipal(identity); var authProperties = new AuthenticationProperties() { IsPersistent = true, ExpiresUtc = lastAuthenticated.AddHours(1) }; await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, authProperties); return Ok(new { Message = "User signed in."}); } else { return Unauthorized(); } }I have Windows Authentication and Anonymous Authentication set to True. Right now initial claims looks like it only is loading in the claims Windows AUthenitcation comes back with automatically, and is not setting the roles from Login.
How can I cause this to, by default, route to login for the SignIn so the user gets the claims immediatly? What mix of authentications am I doing wrong here?