Class: Rack::CASClient
- Inherits:
-
Object
- Object
- Rack::CASClient
- Defined in:
- lib/rack/cas_client.rb
Overview
Middleware component to authenticate with a CAS server.
Constant Summary collapse
- VERSION =
'0.3.0'
Instance Attribute Summary collapse
-
#cas_client ⇒ Object
readonly
Returns the value of attribute cas_client.
-
#request ⇒ Object
readonly
Returns the value of attribute request.
Class Method Summary collapse
-
.require_casclient_deps ⇒ Object
Public: CASCLient depends on these things but does not explicitely require them.
Instance Method Summary collapse
-
#app ⇒ Object
Private: Accessor method for app.
- #authenticated? ⇒ Boolean
-
#call(env) ⇒ Object
Public: Rack interface.
-
#call!(env) ⇒ Object
Private: Rack call method.
-
#initialize(app = nil, opts = {}) ⇒ CASClient
constructor
options - Hash :logger - Logger, must respond to :<< Everything else is used by CASClient::Client#configure.
- #log(msg) ⇒ Object
- #redirect(loc) ⇒ Object
-
#request_url_without_ticket ⇒ Object
return the request.url minus params.
-
#service_ticket(service_url) ⇒ Object
Private: Returns a ticket configured with
service_url
. - #session ⇒ Object
- #user ⇒ Object
Constructor Details
#initialize(app = nil, opts = {}) ⇒ CASClient
options - Hash
:logger - Logger, must respond to :<<
Everything else is used by CASClient::Client#configure. Notable params are:
:cas_base_url - String, your CAS Server base url. raises if not there.
:force_ssl_verification - Bool, force ssl verification? Defaults to true.
29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/rack/cas_client.rb', line 29 def initialize app = nil, opts = {} @app = app # quiet cas_client @logger = opts.delete :logger raise ArgumentError, "invalid logger #{@logger}" if @logger and not @logger.respond_to? :<< opts[:force_ssl_verification] = opts.fetch(:force_ssl_verification, true) @cas_client = ::CASClient::Client.new opts end |
Instance Attribute Details
#cas_client ⇒ Object (readonly)
Returns the value of attribute cas_client.
22 23 24 |
# File 'lib/rack/cas_client.rb', line 22 def cas_client @cas_client end |
#request ⇒ Object (readonly)
Returns the value of attribute request.
22 23 24 |
# File 'lib/rack/cas_client.rb', line 22 def request @request end |
Class Method Details
.require_casclient_deps ⇒ Object
Public: CASCLient depends on these things but does not explicitely require them. Call this method (before any forking) if you care. (You may not if you implement your own #blank? for example.)
13 14 15 16 17 18 19 20 |
# File 'lib/rack/cas_client.rb', line 13 def self.require_casclient_deps # YUCK! These are required for casclient require 'active_support/core_ext/object/blank' # I believe one or the other of these is required (not both) but since # they're stdlib I'm leaving them in. require 'json' require 'yaml' end |
Instance Method Details
#app ⇒ Object
Private: Accessor method for app.
If app is nil, redirects back to the referrer, otherwise, just displays a simple page saying that login was successful.
45 46 47 48 49 50 51 52 53 54 |
# File 'lib/rack/cas_client.rb', line 45 def app @app || lambda{|env| req = Rack::Request.new env if url = req.params['url'] self.redirect url else [200, {'Content-Type'=>'text/plain'},['logged in!']] end } end |
#authenticated? ⇒ Boolean
115 116 117 |
# File 'lib/rack/cas_client.rb', line 115 def authenticated? !user.empty? && log("#{user.inspect} is already authenticated") end |
#call(env) ⇒ Object
Public: Rack interface.
Calls app
if already authenticated.
If not authenticated, redirects user to login server. Login server should redirect back with a ticket param. If ticket is valid, redirect back to original request.
It’s up to the session manager to manage timeouts etc.
65 66 67 |
# File 'lib/rack/cas_client.rb', line 65 def call env dup.call! env end |
#call!(env) ⇒ Object
Private: Rack call method.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/rack/cas_client.rb', line 70 def call! env @request = Rack::Request.new env return app.call(env) if authenticated? service_url = request_url_without_ticket cas_login_url = cas_client.add_service_to_login_url(service_url) if st = service_ticket(service_url) cas_client.validate_service_ticket(st) unless st.has_been_validated? if st.is_valid? log 'ticket is valid' # use string because extra_attributes will always have strings as keys user['username'] = st.user user.merge! st.extra_attributes || {} log "user logged in as #{user.inspect}" redirect service_url else log 'ticket is not valid' user.clear # why? redirect cas_login_url end else log 'No ticket, redirecting to login server' redirect cas_login_url end end |
#log(msg) ⇒ Object
119 120 121 122 123 124 125 |
# File 'lib/rack/cas_client.rb', line 119 def log msg return true unless @logger @logger << msg @logger << "\n" unless msg["\n"] true end |
#redirect(loc) ⇒ Object
127 128 129 130 131 132 133 |
# File 'lib/rack/cas_client.rb', line 127 def redirect loc [302, { 'Content-Type' => 'text/plain', 'Content-Length' => '0', 'Location' => loc}, ['']] end |
#request_url_without_ticket ⇒ Object
return the request.url minus params
136 137 138 139 140 141 142 143 144 |
# File 'lib/rack/cas_client.rb', line 136 def request_url_without_ticket # I feel like this should be in Rack::Request # request['ticket'] = nil # request.url url = request.base_url + request.path query = request.params.dup query.delete 'ticket' query.empty? ? url : "#{url}?#{Rack::Utils.build_nested_query query}" end |
#service_ticket(service_url) ⇒ Object
Private: Returns a ticket configured with service_url
service_url - String, the request url that needs to be validated.
103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/rack/cas_client.rb', line 103 def service_ticket service_url ticket = request.params['ticket'] return unless ticket ticket_class = ticket =~ /^PT-/ ? ::CASClient::ProxyTicket : ::CASClient::ServiceTicket st = ticket_class.new(ticket, service_url, false) log "User has a #{ticket_class}! #{st.inspect}" st end |
#session ⇒ Object
146 147 148 |
# File 'lib/rack/cas_client.rb', line 146 def session request.session end |
#user ⇒ Object
150 151 152 153 |
# File 'lib/rack/cas_client.rb', line 150 def user # session[:cas_user] session[cas_client.username_session_key] ||= {} end |