gunark-rubycas-client 2.0.99 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,18 +1,24 @@
1
1
  = RubyCAS-Client Changelog
2
2
 
3
- == Version 2.1.0 :: In Progress...
3
+ == Version 2.1.0 :: 2009-08-18
4
4
 
5
5
  * New functionality:
6
+ * Added an adapter for the Merb framework. Thanks to Andrew O'Brien and
7
+ Antono Vasiljev.
6
8
  * Implemented single-sign-out functionality. The client will now intercept
7
9
  single-sign-out requests and deal with them appropriately if the
8
10
  :enable_single_sign_out config option is set to true. This is currently
9
- disabled by default.
11
+ disabled by default. (Currently this is only implemented for the Rails
12
+ adapter)
10
13
  * Added logout method to Rails adapter to simplify the logout process. The
11
14
  logout method resets the local Rails session and redirects to the CAS
12
15
  logout page.
16
+ * Added login_url method to the Rails filter. This will return the login
17
+ URL for the current controller; useful when you want to show a "Login"
18
+ link in a gatewayed page for an unauthenticated user.
19
+ * Added cas_server_is_up? method to the client, as requested in issue #5.
13
20
  * Extra user attributes are now automatically unserialized if the incoming data
14
21
  is in YAML format.
15
- * Added cas_server_is_up? method to the client as requested in issue #5.
16
22
 
17
23
  * Changes to existing functionality:
18
24
  * The 'service' parameter in the logout method has been renamed to
@@ -43,6 +49,10 @@
43
49
  stripped from the logout url.
44
50
  * The client will no longer attempt to retrieve a PGT for an IOU that had
45
51
  already been previously retrieved. [yipdw1]
52
+
53
+ * Misc:
54
+ * Added complete CAS client integration examples for Rails and Merb
55
+ applications under /examples.
46
56
 
47
57
  == Version 2.0.1 :: 2008-02-27
48
58
 
data/Manifest.txt CHANGED
@@ -2,11 +2,18 @@ CHANGELOG.txt
2
2
  History.txt
3
3
  LICENSE.txt
4
4
  Manifest.txt
5
- README.txt
5
+ README.rdoc
6
6
  Rakefile
7
+ examples/merb/README.textile
8
+ examples/merb/Rakefile
9
+ examples/merb/merb.thor
10
+ examples/merb/merb_auth_cas.rb
11
+ examples/merb/spec/spec_helper.rb
7
12
  init.rb
8
13
  lib/casclient.rb
9
14
  lib/casclient/client.rb
15
+ lib/casclient/frameworks/merb/filter.rb
16
+ lib/casclient/frameworks/merb/strategy.rb
10
17
  lib/casclient/frameworks/rails/cas_proxy_callback_controller.rb
11
18
  lib/casclient/frameworks/rails/filter.rb
12
19
  lib/casclient/responses.rb
@@ -19,6 +19,10 @@ For general information about the open CAS protocol, please have a look at http:
19
19
  If your organization does not already have a CAS server, you may be interested in RubyCAS-Client's sister project,
20
20
  RubyCAS-Server[http://code.google.com/p/rubycas-server/].
21
21
 
22
+ The RubyCAS-Client package includes adapters for Rails and Merb, although the client library itself can be
23
+ adapted for other frameworks (for example an implementation for Camping is available via the Picnic[http://github.com/zuk/picnic/tree/master]
24
+ library).
25
+
22
26
 
23
27
  == Getting help and reporting problems
24
28
 
@@ -26,13 +30,15 @@ If you need help, try posting to the RubyCAS discussion group at http://groups.g
26
30
 
27
31
  To report problems, please use the Google Code issue tracker at http://code.google.com/p/rubycas-client/issues/list.
28
32
 
33
+ API documentation (i.e. the RDocs) are available at http://rubycas-client.rubyforge.org
34
+
29
35
 
30
36
  == Installation
31
37
 
32
38
  You can download the latest version of RubyCAS-Client from the project's rubyforge page at
33
39
  http://rubyforge.org/projects/rubycas-client.
34
40
 
35
- However, it is easier to install the CAS client into a Ruby on Rails app as a plugin:
41
+ However, if you're using Rails, it's easier to install the CAS client as a plugin:
36
42
 
37
43
  cd <your rails app>
38
44
  ./script/plugin install http://rubycas-client.googlecode.com/svn/trunk/rubycas-client
@@ -46,11 +52,20 @@ you always have the latest bleeding-edge version of RubyCAS-Client:
46
52
 
47
53
  ./script/plugin install -x http://rubycas-client.googlecode.com/svn/trunk/rubycas-client
48
54
 
55
+ With Rails 2.1 or newer, it is also possible to install the plugin directly from the bleeding-edge git repository:
56
+
57
+ ./script/plugin install git://github.com/gunark/rubycas-client.git
49
58
 
50
59
  == Usage Examples
51
60
 
52
- Although RubyCAS-Client can be used with other web Frameworks (for example Camping), the following examples
53
- are aimed at {Ruby on Rails}[http://rubyonrails.org].
61
+ If you'd rather jump right in, have a look at the example Rails and Merb applications pre-configured for CAS
62
+ authentication:
63
+
64
+ http://github.com/gunark/rubycas-client/tree/master/examples
65
+
66
+
67
+ Otherwise, continue reading for a step-by-step guide for integrating RubyCAS-Client with Rails:
68
+
54
69
 
55
70
  ==== Using RubyCAS-Client in Rails controllers
56
71
 
@@ -101,9 +116,9 @@ Here is a more complicated configuration showing most of the configuration optio
101
116
  :logout_url => "https://cas.example.foo/logout",
102
117
  :validate_url => "https://cas.example.foo/proxyValidate",
103
118
  :username_session_key => :cas_user,
104
- :extra_attributes_session_key => :cas_extra_attributes
119
+ :extra_attributes_session_key => :cas_extra_attributes,
105
120
  :logger => cas_logger,
106
- :authenticate_on_every_request => true
121
+ :enable_single_sign_out => true
107
122
  )
108
123
 
109
124
  Note that normally it is not necessary to specify <tt>:login_url</tt>, <tt>:logout_url</tt>, and <tt>:validate_url</tt>.
@@ -128,12 +143,25 @@ the disadvantage is that the filter no longer checks to make sure that the user'
128
143
  In other words it is possible for the user's authentication session to be closed on the CAS server without the
129
144
  client application knowing about it.
130
145
 
131
- In the future RubyCAS-Client will support the new "Single Sign-Out" functionality in CAS 3.1, allowing the server to
132
- notify the client application that the CAS session is closed, but for now it is up to you to handle this by, for example,
133
- by wiping the local <tt>session[:cas_user]</tt> value periodically to force a CAS re-check.
146
+ To address this, RubyCAS-Client now supports the new "Single Sign-Out" functionality in CAS 3.1, allowing the server to
147
+ notify the client application that the CAS session is closed. The client will automatically intercept Single Sign-Out
148
+ requsts from the CAS server, but in order for this to work you must configure your Rails application as follows:
149
+
150
+ 1. The Rails session store must be set to ActiveRecord: <tt>config.action_controller.session_store = :active_record_store</tt>
151
+ 2. The server must be able to read and write to RAILS_ROOT/tmp/sessions. If you are in a clustered environment,
152
+ the contents of this directory must be shared between all server instances.
153
+ 3. Cross-site request forgery protection must be disabled. In your <tt>application.rb</tt>: <tt>self.allow_forgery_protection = false</tt>.
154
+ (Or rather you may want to disable forgery protection only for actions that are behind the CAS filter.)
155
+ 4. Finally, you must add <tt>:enable_single_sign_out => true</tt> to your CAS client config (a similar option must be
156
+ enabled on the CAS server, if you're using RubyCAS-Server).
157
+
158
+ The best way to debug single-sign out functionality is to configure your CAS client with logging (see above) and then watch the
159
+ log to ensure that single-sign out requests from the server are being processed correctly.
160
+
134
161
 
135
- Alternatively, it is possible to disable this authentication persistence behaviour by setting the <tt>:authenticate_on_every_request</tt>
136
- configuration option to true as in the example above.
162
+ Alternatively, it is possible to disable authentication persistence in the client by setting the <tt>:authenticate_on_every_request</tt>
163
+ configuration option to true as, in the example in the previous section. However, this is not recommended as it will almost
164
+ certainly have a deleterious impact on performance and can interfere with certain HTTP transactions (AJAX requests, for example).
137
165
 
138
166
 
139
167
  ==== Defining a 'logout' action
@@ -177,6 +205,9 @@ CAS authentication for all actions in a controller except the index action:
177
205
  # ...
178
206
  end
179
207
 
208
+ To provide a login URL for unauthenticated users:
209
+
210
+ <%= link_to("Login", CASClient::Frameworks::Rails::Filter.login_url(controller)) %>
180
211
 
181
212
  ==== How to act as a CAS proxy
182
213
 
@@ -237,12 +268,12 @@ to authenticate another application:
237
268
 
238
269
  service_uri = "http://some-other-application.example.foo"
239
270
  proxy_granting_ticket = session[:cas_pgt]
240
- ticket = CASClient::Frameworks::Rails::Filter.client.request_proxy_ticket(service_uri, proxy_granting_ticket).ticket
271
+ proxy_ticket = CASClient::Frameworks::Rails::Filter.client.request_proxy_ticket(service_uri, proxy_granting_ticket)
241
272
 
242
- <tt>ticket</tt> should now contain a valid service ticket. You can use it to authenticate other services by sending it and
273
+ <tt>proxy_ticket</tt> should now contain a valid proxy ticket. You can use it to authenticate other services by sending it together with
243
274
  the service URI as parameters to your target application:
244
275
 
245
- http://some-other-application.example.foo?service=#{CGI.encode(ticket.target_service)}&ticket=#{ticket.proxy_ticket}
276
+ http://some-other-application.example.foo?service=#{CGI::escape(proxy_ticket.service)}&ticket=#{proxy_ticket.ticket}
246
277
 
247
278
  This is of course assuming that http://some-other-application.example.foo is also protected by the CAS filter.
248
279
  Note that you should always URI-encode your service parameter inside URIs!
@@ -11,6 +11,8 @@ module CASClient
11
11
  end
12
12
 
13
13
  def configure(conf)
14
+ #TODO: raise error if conf contains unrecognized cas options (this would help detect user typos in the config)
15
+
14
16
  raise ArgumentError, "Missing :cas_base_url parameter!" unless conf[:cas_base_url]
15
17
 
16
18
  @cas_base_url = conf[:cas_base_url].gsub(/\/$/, '')
@@ -66,8 +66,10 @@ module CASClient
66
66
  # built around the old client.
67
67
  controller.session[:casfilteruser] = vr.user
68
68
 
69
- f = store_service_session_lookup(st, controller.session.session_id)
70
- log.debug("Wrote service session lookup file to #{f.inspect} with session id #{controller.session.session_id.inspect}.")
69
+ if config[:enable_single_sign_out]
70
+ f = store_service_session_lookup(st, controller.request.session_options[:id] || controller.session.session_id)
71
+ log.debug("Wrote service session lookup file to #{f.inspect} with session id #{controller.request.session_options[:id] || controller.session.session_id.inspect}.")
72
+ end
71
73
  end
72
74
 
73
75
  # Store the ticket in the session to avoid re-validating the same service
@@ -102,7 +104,10 @@ module CASClient
102
104
  else
103
105
  if returning_from_gateway?(controller)
104
106
  log.info "Returning from CAS gateway without authentication."
105
-
107
+
108
+ # reset, so that we can retry authentication if there is a subsequent request
109
+ controller.session[:cas_sent_to_gateway] = false
110
+
106
111
  if use_gatewaying?
107
112
  log.info "This CAS client is configured to use gatewaying, so we will permit the user to continue without authentication."
108
113
  return true
@@ -127,6 +132,16 @@ module CASClient
127
132
  @@config[:use_gatewaying]
128
133
  end
129
134
 
135
+ # Returns the login URL for the current controller.
136
+ # Useful when you want to provide a "Login" link in a GatewayFilter'ed
137
+ # action.
138
+ def login_url(controller)
139
+ service_url = read_service_url(controller)
140
+ url = client.add_service_to_login_url(service_url)
141
+ log.debug("Generated login url: #{url}")
142
+ return url
143
+ end
144
+
130
145
  # Clears the given controller's local Rails session, does some local
131
146
  # CAS cleanup, and redirects to the CAS logout page. Additionally, the
132
147
  # <tt>request.referer</tt> value from the <tt>controller</tt> instance
@@ -147,8 +162,7 @@ module CASClient
147
162
  end
148
163
 
149
164
  def redirect_to_cas_for_authentication(controller)
150
- service_url = read_service_url(controller)
151
- redirect_url = client.add_service_to_login_url(service_url)
165
+ redirect_url = login_url(controller)
152
166
 
153
167
  if use_gatewaying?
154
168
  controller.session[:cas_sent_to_gateway] = true
@@ -194,16 +208,29 @@ module CASClient
194
208
  # TODO: Maybe check that the request came from the registered CAS server? Although this might be
195
209
  # pointless since it's easily spoofable...
196
210
  si = $~[1]
197
- log.debug "Intercepted single-sign-out request for CAS session #{si.inspect}."
198
211
 
199
- required_sess_store = CGI::Session::ActiveRecordStore
200
- current_sess_store = ActionController::Base.session_options[:database_manager]
212
+ unless config[:enable_single_sign_out]
213
+ log.warn "Ignoring single-sign-out request for CAS session #{si.inspect} because ssout functionality is not enabled (see the :enable_single_sign_out config option)."
214
+ return false
215
+ end
201
216
 
217
+ log.debug "Intercepted single-sign-out request for CAS session #{si.inspect}."
218
+
219
+ begin
220
+ required_sess_store = ActiveRecord::SessionStore
221
+ current_sess_store = ActionController::Base.session_store
222
+ rescue NameError
223
+ # for older versions of Rails (prior to 2.3)
224
+ required_sess_store = CGI::Session::ActiveRecordStore
225
+ current_sess_store = ActionController::Base.session_options[:database_manager]
226
+ end
227
+
228
+
202
229
  if current_sess_store == required_sess_store
203
230
  session_id = read_service_session_lookup(si)
204
-
231
+
205
232
  if session_id
206
- session = CGI::Session::ActiveRecordStore::Session.find_by_session_id(session_id)
233
+ session = current_sess_store::Session.find_by_session_id(session_id)
207
234
  if session
208
235
  session.destroy
209
236
  log.debug("Destroyed #{session.inspect} for session #{session_id.inspect} corresponding to service ticket #{si.inspect}.")
@@ -271,7 +298,7 @@ module CASClient
271
298
  f = File.new(filename_of_service_session_lookup(st), 'w')
272
299
  f.write(sid)
273
300
  f.close
274
- return filename_of_service_session_lookup(st)
301
+ return f.path
275
302
  end
276
303
 
277
304
  # Returns the local Rails session ID corresponding to the given
@@ -71,7 +71,11 @@ module CASClient
71
71
 
72
72
  # unserialize extra attributes
73
73
  @extra_attributes.each do |k, v|
74
- @extra_attributes[k] = YAML.load(v)
74
+ if v.blank?
75
+ @extra_attributes[k] = nil
76
+ else
77
+ @extra_attributes[k] = YAML.load(v)
78
+ end
75
79
  end
76
80
  elsif is_failure?
77
81
  @failure_code = @xml.elements['//cas:authenticationFailure'].attributes['code']
@@ -1,8 +1,8 @@
1
1
  module CASClient #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 2
4
- MINOR = 0
5
- TINY = 99
4
+ MINOR = 1
5
+ TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gunark-rubycas-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.99
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Zukowski
@@ -15,6 +15,7 @@ default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activesupport
18
+ type: :runtime
18
19
  version_requirement:
19
20
  version_requirements: !ruby/object:Gem::Requirement
20
21
  requirements:
@@ -24,6 +25,7 @@ dependencies:
24
25
  version:
25
26
  - !ruby/object:Gem::Dependency
26
27
  name: hoe
28
+ type: :runtime
27
29
  version_requirement:
28
30
  version_requirements: !ruby/object:Gem::Requirement
29
31
  requirements:
@@ -42,13 +44,13 @@ extra_rdoc_files:
42
44
  - History.txt
43
45
  - LICENSE.txt
44
46
  - Manifest.txt
45
- - README.txt
47
+ - README.rdoc
46
48
  files:
47
49
  - CHANGELOG.txt
48
50
  - History.txt
49
51
  - LICENSE.txt
50
52
  - Manifest.txt
51
- - README.txt
53
+ - README.rdoc
52
54
  - Rakefile
53
55
  - init.rb
54
56
  - lib/casclient.rb
@@ -63,6 +65,7 @@ files:
63
65
  - setup.rb
64
66
  has_rdoc: true
65
67
  homepage: http://rubycas-client.rubyforge.org
68
+ licenses:
66
69
  post_install_message:
67
70
  rdoc_options:
68
71
  - --main
@@ -84,7 +87,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
84
87
  requirements: []
85
88
 
86
89
  rubyforge_project: rubycas-client
87
- rubygems_version: 1.2.0
90
+ rubygems_version: 1.3.5
88
91
  signing_key:
89
92
  specification_version: 2
90
93
  summary: Client library for the Central Authentication Service (CAS) protocol.