在Rails应用程序中集成Shibboleth登录验证(Implementing Shibboleth in Rails application)

前面介绍了如何配置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!)

H2
H3
H4
3 columns
2 columns
1 column
Join the conversation now