Я использую devise с несколькими стратегиями аутентификации (SAML использует devise_saml_authenticatable gem):
devise :database_authenticatable, :saml_authenticatable, :timeoutable
Пользователь может войти со стандартной страницы входа devise (аутентификация базы данных) или с помощью SAML. После входа в систему нет никакой разницы в модели, используемой для пользователя (оба способа входа в систему дают одну и ту же модель: Пользователь).
Проблема
Всякий раз, когда у пользователя истекает время, я хочу чтобы перенаправить их на страницу входа, с которой они входили. Выяснение того, какой метод входа в систему был использован, не является проблемой, но я не нашел никакого способа получить доступ к этой информации по истечении времени ожидания.
Фактическое перенаправление происходит в Devise FailureApp. Я установил пользовательский fail_app для пользовательского перенаправления:
class CustomFailureApp < Devise::FailureApp
def redirect_url
if warden_message == :timeout
# Find some way to obtain the login method
redirect_to ...
end
end
end
Теперь мне нужно получить используемый метод входа в этот метод.
То, что я уже пробовал
Я попытался использовать:
Warden::Manager.before_logout do |user, auth, opts|
opts[:login_method] = user.login_method
end
Здесь у меня все еще есть доступ к объекту пользователя и я могу получить метод входа в систему, но все, что я установил в опциях, на самом деле не распространяется на CustomFailureApp.
Затем я попытался:
Warden::Manager.before_failure do |env, opts|
opts[:login_method] = ?
end
Все параметры, которые я здесь установил, распространяются в CustomFailureApp, но у меня нет доступа к пользователю и я не могу определить их метод входа в систему здесь.
Я пытался поиск объекта пользователя в CustomFailureApp из сеанса защиты:
def redirect_url
user = warden.session(:user) # Crashes, session invalid
...
end
Однако это не удается, поскольку сеанс уже был уничтожен. Кроме того, просматривая объект запроса, я не вижу четкой информации, идентифицирующей пользователя.
Подобные решения, которые я не могу использовать
Я знаю, что можно перенаправить пользователя на другой логин страница на основе области действия, как указано в Как определить пользовательский отказ для устройства в случае двух разных моделей: пользователь и активный администратор? . Однако мои пользователи не различаются по объему.
7 лет * go кто-то опубликовал способ, который идентифицирует пользователя в методе Warden::Manager.before_failure
, который я мог бы использовать: { ссылка }. Однако это решение больше не работает / не работает для меня. Я не могу найти какую-либо информацию о пользователе в параметрах запроса (или где-либо еще в запросе), кроме (зашифрованного) сеанса надзирателя, который надзиратель отказывается использовать по истечении времени ожидания.
Вопрос ( s)
Есть ли способ, с помощью которого я могу идентифицировать пользователя в CustomFailureApp или передать информацию в CustomFailureApp из точки, где я могу?
Есть ли способ сделать области видимости различными для пользователи вошли в систему с помощью этих различных методов?
В противном случае, могу ли я сохранить метод входа, используемый другим способом, где я могу получить к нему доступ в CustomFailureApp?
Если нет, есть ли другой способ? чтобы иметь это «перенаправление на правильную страницу входа в систему» в зависимости от того, какой метод входа пользователь использовал раньше?