前面介绍了如何配置Apache2和Shibboleth, 下面总结一下如何在Rails应用中配置和使用Shibboleth。当然,前提是你已经配置好了Phusion Passenger。
Further to the basic configuration to make Shibboleth working with Apache 2, it's time to configure Rails application with Shibboleth. You may want to get Phusion Passenger working first, here is the tutorial: Setting up Phusion Passenger with Apache2.
0) 应用环境Environements
Ubuntu: 16
Apache: 2.4.7
Ruby: 2.3.1
Phusion Passenger: 5.1.5
Shibboleth: 2.5.2
1) 配置Apache 2 (Configure Apache2)
首先,编辑这个文件: /etc/apache2/sites-enabled/default-ssl.conf,添加:(First, edit /etc/apache2/sites-enabled/default-ssl.conf and add):
<Location "/Shibboleth.sso">
Require all granted
PassengerEnabled off
</Location>
还有:
and
<Location "/users/auth/shibboleth">
AuthType shibboleth
ShibRequestSetting requireSession 1
require valid-user
</Location>
2) 配置/开发Rails应用以支持Shibboleth (Configure/develop Rails application to support Shibooleth)
2.1) 添加gem 'omniauth-shibboleth'到Gemfile并运行 (Add gem 'omniauth-shibboleth' into Gemfile and run)
bundle install
2.2) 编辑配置文件 (Edit) config/initializers/devise.rb:
config.omniauth :shibboleth, {:uid_field => 'eppn',
:info_fields => {
:affiliation => lambda {|request_param| request_param.call('unscoped-affiliation').split(';')},
},
}
2.3) 编辑文件 (Edit) app/models/user.rb
添加如下方法 (Add method):
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.provider = auth.provider
user.uid = auth.uid
user.email = auth.uid
user.password = Devise.friendly_token[0,20]
end
end
同时不要忘记添加omniauthable到user.rb前面的声明 (Also add :omniauthable to declaration in user.rb)
2.4) 添加一个控制器 (Add a controller, e.g. app/controllers/omniauthcallbacks_controller.rb)
class OmniauthcallbacksController < Devise::OmniauthCallbacksController
def shibboleth
@user = User.from_omniauth(request.env["omniauth.auth"])
session['shib_user_data'] = request.env["omniauth.auth"]
sign_in_and_redirect @user
end
def failure
redirect_to new_local_user_session_path, :notice => "Cannot login via Shibboleth - redirect to local login ..."
end
end
2.5) 编辑文件 (edit) config/routes.rb
devise_for :users, :controllers => { :omniauth_callbacks => "omniauthcallbacks" }, :skip => [:sessions]
Run:
rails g migration AddColumnsToUsers provider uid
rake db:migrate
2.6) 编辑文件 (edit) routes.rb and add:
devise_scope :user do
match "/users/auth/shibboleth" => "omniauth_callbacks#passthru", as: "new_user_session", via: [:get]
match "/users/sign_in" => "devise/sessions#new", as: "new_local_user_session", via: [:get]
match "/users/sign_in" => "devise/sessions#create", as: "user_session", via: [:post]
match "/users/sign_out" => "devise/sessions#destroy", as: "destroy_user_session", via: [:get]
end
至此,大功告成! (All done!)