protected override Task ApplyResponseChallengeAsync()
        {
            if (Response.StatusCode == 401 && Response.Headers.ContainsKey("WWW-Authenticate") == false)
            {
                var challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode);

                if (challenge != null)
                {
                    AuthenticationProperties challengeProperties = challenge.Properties;

                    if (string.IsNullOrEmpty(challengeProperties.RedirectUri))
                    {
                        throw new ArgumentNullException("RedirectUri");
                    }

                    string protectedProperties = Options.StateDataFormat.Protect(challengeProperties);
                    string handshakeId         = Guid.NewGuid().ToString();

                    WindowsAuthenticationHandshake handshake = new WindowsAuthenticationHandshake()
                    {
                        AuthenticationProperties = challengeProperties
                    };

                    Options.Handshakes.Add(handshakeId, handshake);
                    Response.Redirect(WebUtilities.AddQueryString(Request.PathBase + Options.CallbackPath.Value, "id", handshakeId));
                }
            }

            return(Task.Delay(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)));
        }
        public bool TryGet(string key, out WindowsAuthenticationHandshake handshake)
        {
            bool result = false;
            handshake = null;

            if (handshakeCache.Contains(key))
            {
                object cachedHandshake = handshakeCache[key];
                if (cachedHandshake != null)
                {
                    handshake = cachedHandshake as WindowsAuthenticationHandshake; 
                    result = true;
                }
            }

            return result;
        }
Пример #4
0
        public bool TryGet(string key, out WindowsAuthenticationHandshake handshake)
        {
            bool result = false;

            handshake = null;

            if (handshakeCache.Contains(key))
            {
                object cachedHandshake = handshakeCache[key];
                if (cachedHandshake != null)
                {
                    handshake = cachedHandshake as WindowsAuthenticationHandshake;
                    result    = true;
                }
            }

            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)));
        }
Пример #7
0
 public void Add(string key, WindowsAuthenticationHandshake handshake)
 {
     handshakeCache.Set(key, handshake, GetCacheItemPolicy());
 }
 public void Add(string key, WindowsAuthenticationHandshake handshake)
 {
     handshakeCache.Set(key, handshake, GetCacheItemPolicy());
 }