Example #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 (TryGetPrincipal(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
                        ClearAuthorizationCache(sessionID);
                        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)
                    {
                        CachePrincipal(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)
                    {
                        CachePrincipal(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;
            }));
        }
        /// <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()
        {
            // 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(Task.FromResult <AuthenticationTicket>(null));
            }

            NameValueCollection queryParameters = System.Web.HttpUtility.ParseQueryString(Request.QueryString.Value);

            bool useAlternateSecurityProvider = Options.IsAlternateSecurityProviderResource(Request.Path.Value);

            useAlternateSecurityProvider = useAlternateSecurityProvider || (Options.AuthTestPage == Request.Path.Value && Request.QueryString.HasValue && queryParameters.AllKeys.Contains("useAlternate"));

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

            if (Request.Uri.LocalPath == Options.LogoutPage)
            {
                IIdentity logoutIdentity = new GenericIdentity(sessionID.ToString());
                string[]  logoutRoles    = { "logout" };
                Request.User = new GenericPrincipal(logoutIdentity, logoutRoles);

                return(Task.FromResult <AuthenticationTicket>(null));
            }

            AuthenticationHeaderValue authorization = AuthorizationHeader;

            // Attempt to retrieve the user's credentials that were cached to the user's session
            if (TryGetPrincipal(sessionID, useAlternateSecurityProvider, out SecurityPrincipal securityPrincipal))
            {
                bool useCachedCredentials =
                    Request.User is 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
                    ClearAuthorizationCache(sessionID);
                    securityPrincipal = null;
                }
            }

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

                securityPrincipal = AuthenticateCachedCredentials(authenticationToken, useAlternateSecurityProvider);

                // 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)
                {
                    CachePrincipal(sessionID, securityPrincipal, useAlternateSecurityProvider);
                }
            }

            if (securityPrincipal is null)
            {
                // Pick the appropriate authentication logic based
                // on the authorization type in the HTTP headers
                // or in the URI Parameters if it is using OIDC.
                if (authorization?.Scheme == "Basic")
                {
                    securityPrincipal = AuthenticateBasic(authorization.Parameter, useAlternateSecurityProvider);
                }
                // If the resources contains a code make an Attempt to Authorize via OIDC Auth server
                else if (Request.QueryString.HasValue && queryParameters.AllKeys.Contains("code"))
                {
                    securityPrincipal = AuthenticateCode(useAlternateSecurityProvider);
                }


                else
                {
                    securityPrincipal = AuthenticatePassthrough(useAlternateSecurityProvider);
                }

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

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

            return(Task.FromResult <AuthenticationTicket>(null));
        }