Class: CASClient::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/casclient/client.rb

Overview

The client brokers all HTTP transactions with the CAS server.

Direct Known Subclasses

RestClient

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(conf = nil) ⇒ Client



9
10
11
# File 'lib/casclient/client.rb', line 9

def initialize(conf = nil)
  configure(conf) if conf
end

Instance Attribute Details

#cas_base_urlObject (readonly)

Returns the value of attribute cas_base_url.



4
5
6
# File 'lib/casclient/client.rb', line 4

def cas_base_url
  @cas_base_url
end

#extra_attributes_session_keyObject (readonly)

Returns the value of attribute extra_attributes_session_key.



4
5
6
# File 'lib/casclient/client.rb', line 4

def extra_attributes_session_key
  @extra_attributes_session_key
end

#logObject (readonly)

Returns the value of attribute log.



4
5
6
# File 'lib/casclient/client.rb', line 4

def log
  @log
end

#login_urlObject



36
37
38
# File 'lib/casclient/client.rb', line 36

def 
  @login_url || (cas_base_url + "/login")
end

#logout_url(l_service_url = nil, back_url = nil) ⇒ Object

Returns the CAS server’s logout url.

If a logout_url has not been explicitly configured, the default is cas_base_url + “/logout”.

service_url

Set this if you want the user to be able to immediately log back in. Generally you’ll want to use something like request.referer. Note that this only works with RubyCAS-Server.

back_url

This satisfies section 2.3.1 of the CAS protocol spec. See www.ja-sig.org/products/cas/overview/protocol



76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/casclient/client.rb', line 76

def logout_url(l_service_url = nil, back_url = nil)
  url = @logout_url || (cas_base_url + "/logout")
  l_service_url ||= self.service_url
  if l_service_url || back_url
    uri = URI.parse(url)
    h = uri.query ? query_to_hash(uri.query) : {}
    h['service'] = l_service_url if l_service_url
    h['url'] = back_url if back_url
    uri.query = hash_to_query(h)
    uri.to_s
  else
    url
  end
end

#proxy_callback_urlObject

Returns the value of attribute proxy_callback_url.



7
8
9
# File 'lib/casclient/client.rb', line 7

def proxy_callback_url
  @proxy_callback_url
end

#proxy_retrieval_urlObject

Returns the value of attribute proxy_retrieval_url.



7
8
9
# File 'lib/casclient/client.rb', line 7

def proxy_retrieval_url
  @proxy_retrieval_url
end

#proxy_urlObject



91
92
93
# File 'lib/casclient/client.rb', line 91

def proxy_url
  @proxy_url || (cas_base_url + "/proxy")
end

#service_urlObject

Returns the value of attribute service_url.



4
5
6
# File 'lib/casclient/client.rb', line 4

def service_url
  @service_url
end

#ssl_ca_file_pathObject (readonly)

Returns the value of attribute ssl_ca_file_path.



5
6
7
# File 'lib/casclient/client.rb', line 5

def ssl_ca_file_path
  @ssl_ca_file_path
end

#ssl_cert_pathObject (readonly)

Returns the value of attribute ssl_cert_path.



5
6
7
# File 'lib/casclient/client.rb', line 5

def ssl_cert_path
  @ssl_cert_path
end

#ssl_key_pathObject (readonly)

Returns the value of attribute ssl_key_path.



5
6
7
# File 'lib/casclient/client.rb', line 5

def ssl_key_path
  @ssl_key_path
end

#username_session_keyObject (readonly)

Returns the value of attribute username_session_key.



4
5
6
# File 'lib/casclient/client.rb', line 4

def username_session_key
  @username_session_key
end

#validate_urlObject



40
41
42
# File 'lib/casclient/client.rb', line 40

def validate_url
  @validate_url || (cas_base_url + "/proxyValidate")
end

#verify_ssl_certificateObject (readonly)

Returns the value of attribute verify_ssl_certificate.



5
6
7
# File 'lib/casclient/client.rb', line 5

def verify_ssl_certificate
  @verify_ssl_certificate
end

Instance Method Details

#add_service_to_login_url(service_url) ⇒ Object



210
211
212
213
214
# File 'lib/casclient/client.rb', line 210

def (service_url)
  uri = URI.parse()
  uri.query = (uri.query ? uri.query + "&" : "") + "service=#{CGI.escape(service_url)}"
  uri.to_s
end

#configure(conf) ⇒ Object

Raises:

  • (ArgumentError)


13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/casclient/client.rb', line 13

def configure(conf)
  raise ArgumentError, "Missing :cas_base_url parameter!" unless conf[:cas_base_url]
  
  @cas_base_url      = conf[:cas_base_url].gsub(/\/$/, '')       
  
  @login_url    = conf[:login_url]
  @logout_url   = conf[:logout_url]
  @validate_url = conf[:validate_url]
  @proxy_url    = conf[:proxy_url]
  @service_url  = conf[:service_url]
  @proxy_callback_url  = conf[:proxy_callback_url]
  @proxy_retrieval_url = conf[:proxy_retrieval_url]
  @load_ticket_url = conf[:load_ticket_url]
  @verify_ssl_certificate = conf[:verify_ssl_certificate].nil? ? true : conf[:verify_ssl_certificate]
  @username_session_key         = conf[:username_session_key] || :cas_user
  @extra_attributes_session_key = conf[:extra_attributes_session_key] || :cas_extra_attributes
  @ssl_cert_path = conf[:ssl_cert_path]
  @ssl_key_path = conf[:ssl_key_path]
  @ssl_ca_file_path = conf[:ssl_ca_file_path]
  @log = CASClient::LoggerWrapper.new
  @log.set_real_logger(conf[:logger]) if conf[:logger]
end

#http_connection(uri) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/casclient/client.rb', line 124

def http_connection(uri)
  https = Net::HTTP.new(uri.host, uri.port)
  https.use_ssl = (uri.scheme == 'https')
  https.enable_post_connection_check = true if defined?(http.enable_post_connection_check)
  store = OpenSSL::X509::Store.new
  store.set_default_paths
  https.cert_store = store
  
  # if your setup doesn't have the cacerts in the default place, you can pass a path to cacert.pem, which you can get at http://curl.haxx.se/ca/cacert.pem
  https.ca_file = ssl_ca_file_path unless ssl_ca_file_path.blank?
  unless ssl_cert_path.blank?
    https.cert = OpenSSL::X509::Certificate.new(File.read(ssl_cert_path))
  end
  unless ssl_key_path.blank?
    begin
      https.key = OpenSSL::PKey::DSA.new(File.read(ssl_key_path))
    rescue OpenSSL::PKey::DSAError
      https.key = OpenSSL::PKey::RSA.new(File.read(ssl_key_path))
    end
  end
  
  if verify_ssl_certificate
    log.debug "casclient will verify_ssl_certificate"
    https.verify_mode = OpenSSL::SSL::VERIFY_PEER
  else
    log.debug "casclient will NOT verify_ssl_certificate"
    https.verify_mode = OpenSSL::SSL::VERIFY_NONE
  end
  https
end

#load_ticket_url(ticket_id, l_service_url = nil, back_url = nil) ⇒ Object

calls the loadTicket service of cas server to load a TGT (retrived by Rest for example) into the browser cookie. This allows an implementation of autologin on signup:

1. create user
2. cas_client.get_ticket_granting_ticket_resource(...credentials...)
3. redirect to redirect_to load_ticket_url, passing service if you don't
    have one set globally, and passing the ticket from get_ticket_granting_ticket_resource


52
53
54
55
56
57
58
59
60
61
62
# File 'lib/casclient/client.rb', line 52

def load_ticket_url(ticket_id, l_service_url = nil, back_url = nil)
  url = @load_ticket_url || (cas_base_url + "/loadTicket")
  l_service_url ||= self.service_url
  uri = URI.parse(url)
  h = uri.query ? query_to_hash(uri.query) : {}
  h['tgt'] = ticket_id.to_s
  h['service'] = l_service_url.to_s if l_service_url
  h['url'] = back_url.to_s if back_url
  uri.query = hash_to_query(h)
  uri.to_s
end

#login_to_service(credentials, service) ⇒ Object

Requests a login using the given credentials for the given service; returns a LoginResponse object.



112
113
114
115
116
117
118
119
120
121
122
# File 'lib/casclient/client.rb', line 112

def (credentials, service)
  lt = 
  
  data = credentials.merge(
    :lt => lt,
    :service => service 
  )
  
  res = submit_data_to_cas(, data)
  CASClient::LoginResponse.new(res)
end

#request_login_ticketObject

Requests a login ticket from the CAS server for use in a login request; returns a LoginTicket object.

This only works with RubyCAS-Server, since obtaining login tickets in this manner is not part of the official CAS spec.

Raises:



160
161
162
163
164
165
166
167
168
# File 'lib/casclient/client.rb', line 160

def 
  uri = URI.parse(+'Ticket')
  https = http_connection(uri)
  res = https.post(uri.path, ';')
  
  raise CASException, res.body unless res.kind_of? Net::HTTPSuccess
  
  res.body.strip
end

#request_proxy_ticket(pgt, target_service) ⇒ Object

Requests a proxy ticket from the CAS server for the given service using the given pgt (proxy granting ticket); returns a ProxyTicket object.

The pgt required to request a proxy ticket is obtained as part of a ValidationResponse.



176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/casclient/client.rb', line 176

def request_proxy_ticket(pgt, target_service)
  uri = URI.parse(proxy_url)
  h = uri.query ? query_to_hash(uri.query) : {}
  h['pgt'] = pgt.ticket
  h['targetService'] = target_service
  uri.query = hash_to_query(h)
  
  pr = request_cas_response(uri, ProxyResponse)
  
  pt = ProxyTicket.new(pr.proxy_ticket, target_service)
  pt.response = pr
  
  return pt
end

#retrieve_proxy_granting_ticket(pgt_iou) ⇒ Object

Raises:



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/casclient/client.rb', line 191

def retrieve_proxy_granting_ticket(pgt_iou)
  uri = URI.parse(proxy_retrieval_url)
  uri.query = (uri.query ? uri.query + "&" : "") + "pgtIou=#{CGI.escape(pgt_iou)}"
  retrieve_url = uri.to_s
  
  log.debug "Retrieving PGT for PGT IOU #{pgt_iou.inspect} from #{retrieve_url.inspect}"
  
  uri = URI.parse(uri) unless uri.kind_of? URI
  https = http_connection(uri)
  res = https.start do |conn|
    conn.get("#{uri.path}?#{uri.query}")
  end
  
  
  raise CASException, res.body unless res.kind_of? Net::HTTPSuccess
  
  ProxyGrantingTicket.new(res.body.strip, pgt_iou)
end

#validate_service_ticket(st) ⇒ Object Also known as: validate_proxy_ticket



95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/casclient/client.rb', line 95

def validate_service_ticket(st)
  uri = URI.parse(validate_url)
  h = uri.query ? query_to_hash(uri.query) : {}
  h['service'] = st.service
  h['ticket'] = st.ticket
  h['renew'] = 1 if st.renew
  h['pgtUrl'] = proxy_callback_url if proxy_callback_url
  uri.query = hash_to_query(h)
  
  st.response = request_cas_response(uri, ValidationResponse)
  
  return st
end