コード例 #1
0
        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);
        }
コード例 #2
0
        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;
        }
コード例 #3
0
        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)));
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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;
        }
コード例 #6
0
        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)));
        }
コード例 #7
0
        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)));
        }