CAS single-sign-out

CAS退出登录时会记住上次退出的是哪个系统,当下次你用不同的账户登录时还是会进入那个系统。我们希望每次都走管理服务器,由它根据用户账户的区域来决定跳转到哪里。测试发现,先用nanjingView登录到采集服务器,由于是第一次登录,当然是先登到管理服务器再跳转到采集服务器,于是管理服务器和采集服务器上都有用户登录的session信息,从采集服务器退出后,会删除采集服务器上的登录信息,但是管理服务器上的信息还保存着。再次用root进行登录时,(去掉了destination后),会先到管理服务器,这时发现有用户的session存在,它不会用新的用户信息重新写session,还是用以前的信息,于是我们session[:cas_user]取出来的还是nanjingView,然后这个账户是市级,当然就跳转到采集服务器了,但是到采集服务器后得到的用户信息就会是root的信息,因为这些信息是cas server端过来的,并不是从管理服务器来的。这就解释了为什么没有了destination还是一直会跳转到采集服务器。并不是哪里保存了上次退出登录的地址,就是因为管理服务器一直保存着nanjingView用户的信息。想要解决这个问题,只能退出采集服务器时,也要删除管理服务器上的登录信息。于是就讲到了下面的Sigle-sign-out。

配置Single-sign-out:

  • server端配置文件config.yml
##### SINGLE SIGN-OUT ########################################################## 

# When a user logs in to a CAS-enabled client application, that application
# generally opens its own local user session. When the user then logs out
# through the CAS server, each of the CAS-enabled client applications need
# to be notified so that they can close their own local sessions for that user.
#
# Up until recently this was not possible within CAS. However, a method for
# performing this notification was recently added to the protocol (in CAS 3.1). 
# This works exactly as described above -- when the user logs out, the CAS 
# server individually contacts each client service and notifies it of the 
# logout. Currently not all client applications support this, so this
# behaviour is disabled by default. To enable it, uncomment the following
# configuration line. Note that currently it is not possible to enable
# or disable single-sign-out on a per-service basis, but this functionality
# is planned for a future release. 

#enable_single_sign_out: true

     将enabel_single_sign_out置为true (注释去掉)

1. 项目environment.rb文件添加如下配置:

CASClient::Frameworks::Rails::Filter.configure(
                  :cas_base_url  => "https://cas.example.foo/",
                  :enable_single_sign_out => true
  )

2. /config/initializers中session_store.rb文件修改如下:

# Use the database for sessions instead of the cookie-based default,
# which shouldn't be used to store highly confidential information
# (create the session table with "rake db:sessions:create")
ActionController::Base.session_store = :active_record_store

(去掉最后一行注释,Single-sign-out要求sesison存储用ActiveRecord方式,默认是用 cookie_session方式)

之前在网上看到修改的方式都是这样的 config.action_controller.session_store = :active_record_store ,然后就去environment.rb文件中去改,改完会报错。应该是因为Rails版本升级了,现在需要在session_store.rb文件中修改。

3. 创建session数据表

在项目的根目录下运行 rake db:sessions:create

会在项目db文件夹下生成migrate文件夹,并在其中生成文件 20100507031926_create_sessions.rb,该文件内容如下:

class CreateSessions < ActiveRecord::Migration
  def self.up
    create_table :session do |t|
      t.string :session_id, :null => false
      t.text :data
      t.timestamps
    end 

    add_index :session, :session_id
    add_index :session, :updated_at
  end 

  def self.down
    drop_table :session
  end
end

接着运行命令 rake db:migrate

此时会在项目配置的数据库中生成名为session的数据表,表结构及内容如下图:

image

运行rake可能会遇到错误

rake aborted!

No Rakefile found (looking for: rakefile, Rakefile, rakefile.rb, Rakefile.rb)

这是因为项目根目录中应该有个Rakefile文件,如果缺少拷一份过来就行了。

     image

4. 去掉外键保护

   如果设置了外键保护,会遇到错误 ActionController::InvalidAuthenticityToken

   解决方法:在 application_controller.rb文件将不能有外键保护的方法except

  protect_from_forgery(:except =>[:login,:logoutcas,:logout,:filter,:single_sign_out])
  skip_before_filter :verify_authenticity_token 

  或者修改配置文件config/environments/development.rb

  # Disable request forgery protection in development environment

    config.action_controller.allow_forgery_protection = false

不过这样会造成所有的外键保护都不能用,建议使用第一种方法。

这里的解决方法是参考文章   http://www.javaeye.com/topic/350718

登出系统后去掉destination的方法:

    登出某个系统后,url会带有?destination参数指向登出的系统,下次登录时就会进入该系统,该功能是通过客户端vendor/plugins/rubycas-client/lib/casclient/frameworks/rails中的filter.rb文件中实现:

          # Clears the given controller's local Rails session, does some local 
          # CAS cleanup, and redirects to the CAS logout page. Additionally, the
          # request.referer value from the controller instance 
          # is passed to the CAS server as a 'destination' parameter. This 
          # allows RubyCAS server to provide a follow-up login page allowing
          # the user to log back in to the service they just logged out from 
          # using a different username and password. Other CAS server 
          # implemenations may use this 'destination' parameter in different 
          # ways. 
          # If given, the optional service URL overrides 
          # request.referer.
          def logout(controller, service = nil)
            referer = service || controller.request.referer
            st = controller.session[:cas_last_valid_ticket]
            delete_service_session_lookup(st) if st
            controller.send(:reset_session)
            controller.send(:redirect_to, client.logout_url(referer))
          end

在这里将referer赋值为nil,或者可以在客户端用来logout的方法中进行处理,方法如下:

比方我们自己写了logout_controller.rb文件:

class LogoutController < ApplicationController
  def logoutcas
    self.request.env['HTTP_REFERER']=nil
    CASClient::Frameworks::Rails::Filter.logout(self)
  end
end

self.request.env['HTTP_REFERER']=nil 也可以将http的referer信息清空。

当然你去除了destination参数之后,要在cas服务端的/lib/ruby/gems/1.8/gems/rubycas-server-0.7.999999.20100202/lib/casserver中controllers.rb文件的

Logout类的get方法中把@service赋值:@service = http://192.168.1.84:4000/redirect/redirect,不然casserver验证登录后不知道要跳转到哪里,会就留在登录页面(只告知你登录成功了~)

登录管理服务器根据用户账户跳转:

另一个我们对controllers.rb文件做的修改是,在Login类的get方法中修改@service,

if @service.nil? or @service==""
       @service = "
end

只在@service没有值的情况下强制跳转到redirect方法。

 

总结

以上就是为了让CAS适合我们系统需求所要做的配置和修改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值