public bool TryAcquireServerChallenge(WindowsAuthenticationToken message) { bool result = false; SecurityBufferDesciption clientToken = new SecurityBufferDesciption(message.Data); SecurityBufferDesciption serverToken = new SecurityBufferDesciption(MaximumTokenSize); try { SecurityInteger lifetime = new SecurityInteger(0); uint contextAttributes; if (NativeMethods.AcquireCredentialsHandle(null, "NTLM", SecurityCredentialsInbound, IntPtr.Zero, IntPtr.Zero, 0, IntPtr.Zero, ref credentials, ref lifetime) == 0) { if (NativeMethods.AcceptSecurityContext(ref credentials, IntPtr.Zero, ref clientToken, StandardContextAttributes, SecurityNativeDataRepresentation, out context, out serverToken, out contextAttributes, out lifetime) == IntermediateResult) { result = true; } } } finally { message.Data = serverToken.GetBytes(); clientToken.Dispose(); serverToken.Dispose(); } return(result); }
public bool TryAcquireServerChallenge(WindowsAuthenticationToken message) { bool result = false; SecurityBufferDesciption clientToken = new SecurityBufferDesciption(message.Data); SecurityBufferDesciption serverToken = new SecurityBufferDesciption(MaximumTokenSize); try { SecurityInteger lifetime = new SecurityInteger(0); uint contextAttributes; if (NativeMethods.AcquireCredentialsHandle(null, "NTLM", SecurityCredentialsInbound, IntPtr.Zero, IntPtr.Zero, 0, IntPtr.Zero, ref credentials, ref lifetime) == 0) { if (NativeMethods.AcceptSecurityContext(ref credentials, IntPtr.Zero, ref clientToken, StandardContextAttributes, SecurityNativeDataRepresentation, out context, out serverToken, out contextAttributes, out lifetime) == IntermediateResult) { result = true; } } } finally { message.Data = serverToken.GetBytes(); clientToken.Dispose(); serverToken.Dispose(); } return result; }
protected override Task <AuthenticationTicket> AuthenticateCoreAsync() { AuthenticationProperties properties = null; WindowsAuthenticationHandshake handshake = null; string handshakeId = Request.Query["id"]; if (handshakeId != null && Options.Handshakes.TryGet(handshakeId, out handshake)) { WindowsAuthenticationToken token = WindowsAuthenticationToken.Create(Request.Headers["Authorization"]); switch (token.AuthorizationStage) { case AuthenticationStage.Request: if (handshake.TryAcquireServerChallenge(token)) { Response.Headers.Add("WWW-Authenticate", new[] { string.Concat("NTLM ", token.Challenge) }); Response.StatusCode = 401; return(Task.FromResult(new AuthenticationTicket(null, properties))); } break; case AuthenticationStage.Response: if (handshake.IsClientResponseValid(token)) { properties = handshake.AuthenticationProperties; if (Options.GetClaimsForUser != null) { Claim[] claims = Options.GetClaimsForUser(handshake.AuthenticatedUsername).ToArray(); if (claims.Length > 0) { ClaimsIdentity identity = new ClaimsIdentity(Options.SignInAsAuthenticationType); identity.AddClaims(claims); identity.AddClaim(new Claim(ClaimTypes.AuthenticationMethod, WindowsAuthenticationDefaults.AuthenticationType)); Options.Handshakes.TryRemove(handshakeId); return(Task.FromResult(new AuthenticationTicket(identity, properties))); } } } break; } Response.Headers.Add("WWW-Authenticate", new[] { "NTLM" }); Response.StatusCode = 401; } return(Task.FromResult(new AuthenticationTicket(null, properties))); }
public bool IsClientResponseValid(WindowsAuthenticationToken token) { bool result = false; SecurityBufferDesciption clientToken = new SecurityBufferDesciption(token.Data); SecurityBufferDesciption serverToken = new SecurityBufferDesciption(MaximumTokenSize); IntPtr securityContextHandle = IntPtr.Zero; try { uint contextAttributes; var lifetime = new SecurityInteger(0); if (NativeMethods.AcceptSecurityContext(ref credentials, ref context, ref clientToken, StandardContextAttributes, SecurityNativeDataRepresentation, out context, out serverToken, out contextAttributes, out lifetime) == 0) { if (NativeMethods.QuerySecurityContextToken(ref context, ref securityContextHandle) == 0) { using (WindowsIdentity identity = new WindowsIdentity(securityContextHandle)) { if (identity != null) { AuthenticatedUsername = identity.Name; result = true; } } } } } finally { clientToken.Dispose(); serverToken.Dispose(); NativeMethods.CloseHandle(securityContextHandle); credentials.Reset(); context.Reset(); } return(result); }
public bool IsClientResponseValid(WindowsAuthenticationToken token) { bool result = false; SecurityBufferDesciption clientToken = new SecurityBufferDesciption(token.Data); SecurityBufferDesciption serverToken = new SecurityBufferDesciption(MaximumTokenSize); IntPtr securityContextHandle = IntPtr.Zero; try { uint contextAttributes; var lifetime = new SecurityInteger(0); if (NativeMethods.AcceptSecurityContext(ref credentials, ref context, ref clientToken, StandardContextAttributes, SecurityNativeDataRepresentation, out context, out serverToken, out contextAttributes, out lifetime) == 0) { if (NativeMethods.QuerySecurityContextToken(ref context, ref securityContextHandle) == 0) { using (WindowsIdentity identity = new WindowsIdentity(securityContextHandle)) { if (identity != null) { AuthenticatedUsername = identity.Name; result = true; } } } } } finally { clientToken.Dispose(); serverToken.Dispose(); NativeMethods.CloseHandle(securityContextHandle); credentials.Reset(); context.Reset(); } return result; }
protected override Task <AuthenticationTicket> AuthenticateCoreAsync() { AuthenticationProperties properties = null; WindowsAuthenticationHandshake handshake = null; string handshakeId = Request.Query["id"]; if (handshakeId != null && Options.Handshakes.TryGet(handshakeId, out handshake)) { WindowsAuthenticationToken token = WindowsAuthenticationToken.Create(Request.Headers["Authorization"]); switch (token.AuthorizationStage) { case AuthenticationStage.Request: if (handshake.TryAcquireServerChallenge(token)) { Response.Headers.Add("WWW-Authenticate", new[] { string.Concat("NTLM ", token.Challenge) }); Response.StatusCode = 401; return(Task.FromResult(new AuthenticationTicket(null, properties))); } break; case AuthenticationStage.Response: if (handshake.IsClientResponseValid(token)) { properties = handshake.AuthenticationProperties; var uid = handshake.AuthenticatedUsername.ToLowerInvariant(); var claimdelegate = Options.GetClaimsForUser(uid); if (claimdelegate == null) { var dc = new PrincipalContext(ContextType.Domain, handshake.AuthenticatedUsername.GetDomain()); var adUser = UserPrincipal.FindByIdentity(dc, handshake.AuthenticatedUsername); ClaimsIdentity identity = new ClaimsIdentity(Options.SignInAsAuthenticationType); List <Claim> result = new List <Claim>(); result.Add(new Claim(ClaimTypes.Name, adUser.GivenName)); result.Add(new Claim(ClaimTypes.Surname, adUser.Surname)); result.Add(new Claim(ClaimTypes.Upn, adUser.Guid.ToString())); result.Add(new Claim(ClaimTypes.NameIdentifier, handshake.AuthenticatedUsername)); result.Add(new Claim(ClaimTypes.Email, adUser.EmailAddress)); result.Add(new Claim(ClaimTypes.Role, Definitions.Roles.Administrator)); result.Add(new Claim(ClaimTypes.Role, "Administrator")); identity.AddClaims(result); identity.AddClaim(new Claim(ClaimTypes.AuthenticationMethod, WindowsAuthenticationDefaults.AuthenticationType)); Options.Handshakes.TryRemove(handshakeId); // user does not exist! Redirect to create page. properties.RedirectUri = "/Account/CreateADUser"; return(Task.FromResult(new AuthenticationTicket(identity, properties))); } else { Claim[] claims = claimdelegate.ToArray(); if (claims.Length > 0) { ClaimsIdentity identity = new ClaimsIdentity(Options.SignInAsAuthenticationType); identity.AddClaims(claims); identity.AddClaim(new Claim(ClaimTypes.AuthenticationMethod, WindowsAuthenticationDefaults.AuthenticationType)); Options.Handshakes.TryRemove(handshakeId); return(Task.FromResult(new AuthenticationTicket(identity, properties))); } } } break; } Response.Headers.Add("WWW-Authenticate", new[] { "NTLM" }); Response.StatusCode = 401; } return(Task.FromResult(new AuthenticationTicket(null, properties))); }
protected override Task <AuthenticationTicket> AuthenticateCoreAsync() { AuthenticationProperties properties = null; WindowsAuthenticationHandshake handshake = null; string handshakeId = Request.Query["id"]; if (handshakeId != null && Options.Handshakes.TryGet(handshakeId, out handshake)) { WindowsAuthenticationToken token = WindowsAuthenticationToken.Create(Request.Headers["Authorization"]); switch (token.AuthorizationStage) { case AuthenticationStage.Request: if (handshake.TryAcquireServerChallenge(token)) { Log.Verbose("WinAuth: Obtained challenge token OK"); Response.Headers.Add("WWW-Authenticate", new[] { string.Concat("NTLM ", token.Challenge) }); Response.StatusCode = 401; return(Task.FromResult(new AuthenticationTicket(null, properties))); } break; case AuthenticationStage.Response: if (handshake.IsClientResponseValid(token)) { properties = handshake.AuthenticationProperties; var uid = handshake.AuthenticatedUsername.ToLowerInvariant(); var claimdelegate = Options.GetClaimsForUser(uid); Log.Verbose("WinAuth: Valid response for uid {UserId}", uid); if (claimdelegate == null) { string domainName = handshake.AuthenticatedUsername.GetDomain(); Log.Verbose("WinAuth: New user - looking-up user {UserName} in domain {DomainName}", handshake.AuthenticatedUsername, domainName); var dc = new PrincipalContext(ContextType.Domain, domainName); var adUser = UserPrincipal.FindByIdentity(dc, handshake.AuthenticatedUsername); if (adUser == null) { Log.Error("DC for domain {DomainName} has returned null for username {UserName} - failing auth", domainName, handshake.AuthenticatedUsername); Response.StatusCode = 401; return(Task.FromResult(new AuthenticationTicket(null, null))); } Log.Verbose("WinAuth: DC returned adUser {ADUser}", adUser.GivenName); ClaimsIdentity identity = new ClaimsIdentity(Options.SignInAsAuthenticationType); List <Claim> result = new List <Claim>(); if (!String.IsNullOrEmpty(adUser.GivenName)) { result.Add(new Claim(ClaimTypes.GivenName, adUser.GivenName)); } if (!String.IsNullOrEmpty(adUser.Surname)) { result.Add(new Claim(ClaimTypes.Surname, adUser.Surname)); } result.Add(new Claim(ClaimTypes.NameIdentifier, adUser.Guid.ToString())); result.Add(new Claim(ClaimTypes.Name, handshake.AuthenticatedUsername)); if (!String.IsNullOrEmpty(adUser.EmailAddress)) { result.Add(new Claim(ClaimTypes.Email, adUser.EmailAddress)); } identity.AddClaims(result); identity.AddClaim(new Claim(ClaimTypes.AuthenticationMethod, WindowsAuthenticationDefaults.AuthenticationType)); Options.Handshakes.TryRemove(handshakeId); Log.Verbose("WinAuth: New user - about to redirect to CreateADUser"); // user does not exist! Redirect to create page. properties.RedirectUri = "/Account/CreateADUser"; return(Task.FromResult(new AuthenticationTicket(identity, properties))); } else { Claim[] claims = claimdelegate.ToArray(); Log.Verbose("WinAuth: Found existing uid {UserId}, has {Claims} claims", uid, claims.Length); if (claims.Length > 0) { ClaimsIdentity identity = new ClaimsIdentity(Options.SignInAsAuthenticationType); identity.AddClaims(claims); identity.AddClaim(new Claim(ClaimTypes.AuthenticationMethod, WindowsAuthenticationDefaults.AuthenticationType)); Options.Handshakes.TryRemove(handshakeId); Log.Verbose("WinAuth: Returning id auth ticket, claims: {Claims}", claims); return(Task.FromResult(new AuthenticationTicket(identity, properties))); } } } break; } Response.Headers.Add("WWW-Authenticate", new[] { "NTLM" }); Response.StatusCode = 401; } return(Task.FromResult(new AuthenticationTicket(null, properties))); }