我的应用程序已集成了Devise,我希望允许Apache通过SAML(向IdP身份提供者)对用户进行身份验证。成功登录SAML后,Apache然后可以传递一个指示user_identifier的环境变量。
但是,我不知道如何告诉Devise(或Warden)该用户现在已经登录,并且不显示登录页面。
routes.rb类似于:
Authentication::Engine.routes.draw do
devise_for :user, {
class_name: 'Authentication::Account',
module: :devise,
path_names: {
sign_up: 'register',
cancel: '',
},
controllers: {
# ...
sessions: 'authentication/sessions',
}
}
devise_scope :user do
root to: 'sessions#new'
# ...
end
我通过向SessionsController添加new()方法进行了几次尝试:
module Authentication
class SessionsController < Devise::SessionsController
before_action :authenticate_user!, :except => [:new, :create], raise: false
prepend_before_action(only: [:new, :create, :destroy]) { request.env["devise.skip_timeout"] = true}
def destroy
# ...
end
# add new() method to override default Devise method
def new
user_identifier = ENV['uid']
@user = Account.find_by_user_identifier(user_identifier)
# super do
store_location_for(:user, session[:origin_url])
# dependent upon prepend_before_action, see rubydoc.info
# sign_in(@user) # didn't seem to sign user in, redirectors controller then calls destroy (above)
bypass_sign_in(@user)
# redirect_to session[:origin_url] and return
# sign_in_and_redirect session[:origin_url] and return # wrong?
# sign_in_and_redirect @user # wrong, loops through sign_in
# resource = warden.authenticate!(:scope => :user, :recall session[:origin_url])
# resource = warden.authenticate!(:scope => :user) # maybe?
# sign_in_and_redirect(:user, resource)
# redirect_to session[:origin_url] and return
# end
end
大多数尝试都会导致将用户发送到登录页面,而其他尝试则导致无限循环。
将其他身份验证方法添加到Devise的正确方法是通过OmniAuth(标准化的多提供商身份验证)
摘自文档:“ OmniAuth是一个标准化Web应用程序多提供商身份验证的库。创建该库的目的是强大,灵活且操作尽可能少。任何开发人员都可以为OmniAuth创建可以验证用户身份的策略通过不同的系统。“