Exemplo n.º 1
0
        /// <summary>
        /// The core authentication logic which must be provided by the handler. Will be invoked at most
        /// once per request. Do not call directly, call the wrapping Authenticate method instead.
        /// </summary>
        /// <returns>The ticket data provided by the authentication logic</returns>
        protected override Task <AuthenticationTicket> AuthenticateCoreAsync()
        {
            return(Task.Run(() =>
            {
                SecurityPrincipal securityPrincipal;

                // Track original principal
                Request.Environment["OriginalPrincipal"] = Request.User;
                Request.Environment["AuthenticationOptions"] = Options.Readonly;

                // No authentication required for anonymous resources
                if (Options.IsAnonymousResource(Request.Path.Value))
                {
                    return null;
                }

                // Attempt to read the session ID from the HTTP cookies
                Guid sessionID = SessionHandler.GetSessionIDFromCookie(Request, Options.SessionToken);
                AuthenticationHeaderValue authorization = AuthorizationHeader;

                // Attempt to retrieve the user's credentials that were cached to the user's session
                if (s_authorizationCache.TryGetValue(sessionID, out securityPrincipal))
                {
                    bool useCachedCredentials =
                        (object)Request.User == null ||
                        Request.User.Identity.Name.Equals(securityPrincipal.Identity.Name, StringComparison.OrdinalIgnoreCase) ||
                        authorization?.Scheme != "Basic";

                    if (!useCachedCredentials)
                    {
                        // Explicit login attempts as a different user
                        // cause credentials to be flushed from the session
                        s_authorizationCache.TryRemove(sessionID, out securityPrincipal);
                        securityPrincipal = null;
                    }
                }

                if ((object)authorization == null && (object)securityPrincipal == null)
                {
                    // Attempt to authenticate using cached credentials associated with the authentication token cookie
                    string authenticationToken = SessionHandler.GetAuthenticationTokenFromCookie(Request, Options.AuthenticationToken);

                    securityPrincipal = AuthenticateCachedCredentials(authenticationToken);

                    // If authentication using cached credentials fails,
                    // fall back on the other authentication methods
                    if (securityPrincipal?.Identity.IsAuthenticated != true)
                    {
                        securityPrincipal = null;
                    }

                    // Attempt to cache the security principal to the session
                    if (sessionID != Guid.Empty && securityPrincipal?.Identity.IsAuthenticated == true)
                    {
                        s_authorizationCache[sessionID] = securityPrincipal;
                    }
                }

                if ((object)securityPrincipal == null)
                {
                    // Pick the appropriate authentication logic based
                    // on the authorization type in the HTTP headers
                    if (authorization?.Scheme == "Basic")
                    {
                        securityPrincipal = AuthenticateBasic(authorization.Parameter);
                    }
                    else
                    {
                        securityPrincipal = AuthenticatePassthrough();
                    }

                    // Attempt to cache the security principal to the session
                    if (sessionID != Guid.Empty && securityPrincipal?.Identity.IsAuthenticated == true)
                    {
                        s_authorizationCache[sessionID] = securityPrincipal;
                    }
                }

                // Set the principal of the IOwinRequest so that it
                // can be propagated through the Owin pipeline
                Request.User = securityPrincipal ?? AnonymousPrincipal;

                return (AuthenticationTicket)null;
            }));
        }