public InteractionResponse ProcessLogin(ValidatedAuthorizeRequest request, ClaimsPrincipal user)
        {
            // pass through display mode to signin service
            if (request.DisplayMode.IsPresent())
            {
                _signIn.DisplayMode = request.DisplayMode;
            }

            // pass through ui locales to signin service
            if (request.UiLocales.IsPresent())
            {
                _signIn.UILocales = request.UiLocales;
            }

            if (request.PromptMode == Constants.PromptModes.Login)
            {
                // remove prompt so when we redirect back in from login page
                // we won't think we need to force a prompt again
                request.Raw.Remove(Constants.AuthorizeRequest.Prompt);
                return new InteractionResponse
                {
                    IsLogin = true,
                    SignInMessage = _signIn
                };
            }

            // unauthenticated user
            if (!user.Identity.IsAuthenticated)
            {
                // prompt=none means user must be signed in already
                if (request.PromptMode == Constants.PromptModes.None)
                {
                    return new InteractionResponse
                    {
                        IsError = true,
                        Error = new AuthorizeError
                        {
                            ErrorType = ErrorTypes.Client,
                            Error = Constants.AuthorizeErrors.InteractionRequired,
                            ResponseMode = request.ResponseMode,
                            ErrorUri = request.RedirectUri,
                            State = request.State
                        }
                    };
                }

                return new InteractionResponse
                {
                    IsLogin = true,
                    SignInMessage = _signIn
                };
            }

            // check authentication freshness
            if (request.MaxAge.HasValue)
            {
                var authTime = user.GetAuthenticationTime();
                if (DateTime.UtcNow > authTime.AddSeconds(request.MaxAge.Value))
                {
                    return new InteractionResponse
                    {
                        IsLogin = true,
                        SignInMessage = _signIn
                    };
                }
            }
    
            return new InteractionResponse();
        }
        public async Task<LoginInteractionResponse> ProcessLoginAsync(ValidatedAuthorizeRequest request, ClaimsPrincipal user)
        {
            // let the login page know the client requesting authorization
            _signIn.ClientId = request.ClientId;
            
            // pass through display mode to signin service
            if (request.DisplayMode.IsPresent())
            {
                _signIn.DisplayMode = request.DisplayMode;
            }

            // pass through ui locales to signin service
            if (request.UiLocales.IsPresent())
            {
                _signIn.UiLocales = request.UiLocales;
            }

            // pass through login_hint
            if (request.LoginHint.IsPresent())
            {
                _signIn.LoginHint = request.LoginHint;
            }

            // process acr values
            var acrValues = request.AuthenticationContextReferenceClasses.Distinct().ToList();
            
            // look for well-known acr value -- idp
            var idp = acrValues.FirstOrDefault(x => x.StartsWith(Constants.KnownAcrValues.HomeRealm));
            if (idp.IsPresent())
            {
                _signIn.IdP = idp.Substring(Constants.KnownAcrValues.HomeRealm.Length);
                acrValues.Remove(idp);
            }

            // look for well-known acr value -- tenant
            var tenant = acrValues.FirstOrDefault(x => x.StartsWith(Constants.KnownAcrValues.Tenant));
            if (tenant.IsPresent())
            {
                _signIn.Tenant = tenant.Substring(Constants.KnownAcrValues.Tenant.Length);
                acrValues.Remove(tenant);
            }

            // pass through any remaining acr values
            if (acrValues.Any())
            {
                _signIn.AcrValues = acrValues;
            }

            if (request.PromptMode == Constants.PromptModes.Login)
            {
                // remove prompt so when we redirect back in from login page
                // we won't think we need to force a prompt again
                request.Raw.Remove(Constants.AuthorizeRequest.Prompt);

                Logger.Info("Redirecting to login page because of prompt=login");

                return new LoginInteractionResponse
                {
                    SignInMessage = _signIn
                };
            }

            // unauthenticated user
            var isAuthenticated = user.Identity.IsAuthenticated;
            if (!isAuthenticated) Logger.Info("User is not authenticated. Redirecting to login.");
            
            // user de-activated
            bool isActive = false;

            if (isAuthenticated)
            {
                var isActiveCtx = new IsActiveContext(user, request.Client);
                await _users.IsActiveAsync(isActiveCtx);
                
                isActive = isActiveCtx.IsActive; 
                if (!isActive) Logger.Info("User is not active. Redirecting to login.");
            }

            if (!isAuthenticated || !isActive)
            {
                // prompt=none means user must be signed in already
                if (request.PromptMode == Constants.PromptModes.None)
                {
                    Logger.Info("prompt=none was requested. But user is not authenticated.");

                    return new LoginInteractionResponse
                    {
                        Error = new AuthorizeError
                        {
                            ErrorType = ErrorTypes.Client,
                            Error = Constants.AuthorizeErrors.LoginRequired,
                            ResponseMode = request.ResponseMode,
                            ErrorUri = request.RedirectUri,
                            State = request.State
                        }
                    };
                }

                return new LoginInteractionResponse
                {
                    SignInMessage = _signIn
                };
            }

            // check current idp
            var currentIdp = user.GetIdentityProvider();

            // check if idp login hint matches current provider
            if (_signIn.IdP.IsPresent())
            {
                if (_signIn.IdP != currentIdp)
                {
                    Logger.Info("Current IdP is not the requested IdP. Redirecting to login");
                    Logger.InfoFormat("Current: {0} -- Requested: {1}", currentIdp, _signIn.IdP);

                    return new LoginInteractionResponse
                    {
                        SignInMessage = _signIn
                    };
                }
            }

            // check authentication freshness
            if (request.MaxAge.HasValue)
            {
                var authTime = user.GetAuthenticationTime();
                if (DateTimeOffsetHelper.UtcNow > authTime.AddSeconds(request.MaxAge.Value))
                {
                    Logger.Info("Requested MaxAge exceeded. Redirecting to login");

                    return new LoginInteractionResponse
                    {
                        SignInMessage = _signIn
                    };
                }
            }

            return new LoginInteractionResponse();
        }
        public async Task<LoginInteractionResponse> ProcessLoginAsync(ValidatedAuthorizeRequest request, ClaimsPrincipal user)
        {
            // let the login page know the client requesting authorization
            _signIn.ClientId = request.ClientId;

            // pass through display mode to signin service
            if (request.DisplayMode.IsPresent())
            {
                _signIn.DisplayMode = request.DisplayMode;
            }

            // pass through ui locales to signin service
            if (request.UiLocales.IsPresent())
            {
                _signIn.UiLocales = request.UiLocales;
            }

            // check login_hint - we only support idp: right now
            if (request.LoginHint.IsPresent())
            {
                if (request.LoginHint.StartsWith(Constants.LoginHints.HomeRealm))
                {
                    _signIn.IdP = request.LoginHint.Substring(Constants.LoginHints.HomeRealm.Length);
                }
                if (request.LoginHint.StartsWith(Constants.LoginHints.Tenant))
                {
                    _signIn.Tenant = request.LoginHint.Substring(Constants.LoginHints.Tenant.Length);
                }
            }

            // pass through acr values
            if (request.AuthenticationContextReferenceClasses.Any())
            {
                _signIn.AcrValues = request.AuthenticationContextReferenceClasses;
            }

            if (request.PromptMode == Constants.PromptModes.Login)
            {
                // remove prompt so when we redirect back in from login page
                // we won't think we need to force a prompt again
                request.Raw.Remove(Constants.AuthorizeRequest.Prompt);
                return new LoginInteractionResponse
                {
                    SignInMessage = _signIn
                };
            }

            // unauthenticated user
            var isAuthenticated = user.Identity.IsAuthenticated;
            if (!isAuthenticated) Logger.Info("User is not authenticated. Redirecting to login.");
            
            // user de-activated
            bool isActive = false;

            if (isAuthenticated)
            {
                isActive = await _users.IsActiveAsync(user);
                if (!isActive) Logger.Info("User is not active. Redirecting to login.");
            }

            if (!isAuthenticated || !isActive)
            {
                // prompt=none means user must be signed in already
                if (request.PromptMode == Constants.PromptModes.None)
                {
                    return new LoginInteractionResponse
                    {
                        Error = new AuthorizeError
                        {
                            ErrorType = ErrorTypes.Client,
                            Error = Constants.AuthorizeErrors.LoginRequired,
                            ResponseMode = request.ResponseMode,
                            ErrorUri = request.RedirectUri,
                            State = request.State
                        }
                    };
                }

                return new LoginInteractionResponse
                {
                    SignInMessage = _signIn
                };
            }

            // check current idp
            var currentIdp = user.GetIdentityProvider();

            // check if idp login hint matches current provider
            if (_signIn.IdP.IsPresent())
            {
                if (_signIn.IdP != currentIdp)
                {
                    return new LoginInteractionResponse
                    {
                        SignInMessage = _signIn
                    };
                }
            }

            // check authentication freshness
            if (request.MaxAge.HasValue)
            {
                var authTime = user.GetAuthenticationTime();
                if (DateTimeOffsetHelper.UtcNow > authTime.AddSeconds(request.MaxAge.Value))
                {
                    return new LoginInteractionResponse
                    {
                        SignInMessage = _signIn
                    };
                }
            }

            return new LoginInteractionResponse();
        }