rack-cas 0.9.2 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/{README.markdown → README.md} +68 -68
- data/lib/rack-cas.rb +9 -1
- data/lib/rack-cas/configuration.rb +36 -0
- data/lib/rack-cas/service_validation_response.rb +4 -1
- data/lib/rack-cas/version.rb +1 -1
- data/lib/rack/cas.rb +7 -16
- data/lib/rack/fake_cas.rb +9 -1
- metadata +20 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d5489d9f59ed22ec943c535fa71d22767989376f
|
4
|
+
data.tar.gz: 96d2bb87575ba742f39d8afc7ba15827eb44aa60
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8f3844078c537810c728a96f37631aaa158df1935b696a5cbe9806810c0375db71070b401d80460b86f515a30dcbd94946a213b8ebe68922842b189be67df2db
|
7
|
+
data.tar.gz: e2f627bcdf127c60a051d1152d1f4a294e23fc6466275a5374f09f7f97107ebb0d8dae0aa0e54cb27c171b2609ed5db5b6844fc365680c9c5d3f50ff8c91e8d7
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Rack-CAS [![Build Status](https://travis-ci.org/biola/rack-cas.png?branch=master)](https://travis-ci.org/biola/rack-cas)
|
2
2
|
========
|
3
|
-
Rack-CAS is simple [Rack](http://rack.github.com/) middleware to perform [CAS](http://
|
3
|
+
Rack-CAS is simple [Rack](http://rack.github.com/) middleware to perform [CAS](http://en.wikipedia.org/wiki/Central_Authentication_Service) client authentication.
|
4
4
|
|
5
5
|
Features
|
6
6
|
========
|
@@ -19,7 +19,7 @@ One of the included session stores must be used.
|
|
19
19
|
Requirements
|
20
20
|
============
|
21
21
|
* Ruby >= 1.9.2
|
22
|
-
* A working [CAS server](http://
|
22
|
+
* A working [CAS server](http://casino.rbcas.com)
|
23
23
|
* An app that [returns a `401 Unauthorized`](#integration) status when authentication is requried
|
24
24
|
|
25
25
|
Installation
|
@@ -31,54 +31,54 @@ Rails
|
|
31
31
|
Add `gem 'rack-cas'` to your [`Gemfile`](http://gembundler.com/gemfile.html) and run `bundle install`
|
32
32
|
|
33
33
|
Once the necessary gems have been installed, in your `config/application.rb` add:
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
```ruby
|
35
|
+
config.rack_cas.server_url = 'https://cas.example.com/'
|
36
|
+
```
|
37
37
|
If the the server URL depends on your environment, you can define it in the according file: `config/environments/<env>.rb`
|
38
38
|
|
39
|
-
### Single
|
39
|
+
### Single Logout ###
|
40
40
|
|
41
|
-
If you wish to enable [single
|
41
|
+
If you wish to enable [single logout](http://jasig.github.io/cas/4.0.0/installation/Logout-Single-Signout.html) you'll need to modify your configuration as below.
|
42
42
|
|
43
43
|
#### Active Record ####
|
44
44
|
|
45
45
|
Set the `session_store` in your `config/application.rb`:
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
46
|
+
```ruby
|
47
|
+
require 'rack-cas/session_store/active_record'
|
48
|
+
config.rack_cas.session_store = RackCAS::ActiveRecordStore
|
49
|
+
```
|
50
50
|
Edit your `config/initializers/session_store.rb` file with the following:
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
51
|
+
```ruby
|
52
|
+
require 'rack-cas/session_store/rails/active_record'
|
53
|
+
YourApp::Application.config.session_store :rack_cas_active_record_store
|
54
|
+
```
|
55
55
|
Run:
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
56
|
+
```ruby
|
57
|
+
rails generate cas_session_store_migration
|
58
|
+
rake db:migrate
|
59
|
+
```
|
60
60
|
#### Mongoid ####
|
61
61
|
|
62
62
|
Set the `session_store` in your `config/application.rb`:
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
63
|
+
```ruby
|
64
|
+
require 'rack-cas/session_store/mongoid'
|
65
|
+
config.rack_cas.session_store = RackCAS::MongoidStore
|
66
|
+
```
|
67
67
|
Edit your `config/initializers/session_store.rb` file with the following:
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
68
|
+
```ruby
|
69
|
+
require 'rack-cas/session_store/rails/mongoid'
|
70
|
+
YourApp::Application.config.session_store :rack_cas_mongoid_store
|
71
|
+
```
|
72
72
|
Sinatra and Other Rack-Compatible Frameworks
|
73
73
|
--------------------------------------------
|
74
74
|
|
75
75
|
Add `gem 'rack-cas'` to your [`Gemfile`](http://gembundler.com/gemfile.html) and run `bundle install`
|
76
76
|
|
77
77
|
Add the following to your `config.ru` file:
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
78
|
+
```ruby
|
79
|
+
require 'rack/cas'
|
80
|
+
use Rack::CAS, server_url: 'https://login.example.com/cas'
|
81
|
+
```
|
82
82
|
See the [example Sinatra app](https://gist.github.com/adamcrown/a7e757759469033584c4) to get started.
|
83
83
|
|
84
84
|
### Single Sign Out ###
|
@@ -92,25 +92,25 @@ Excluding Paths
|
|
92
92
|
---------------
|
93
93
|
|
94
94
|
If you have some parts of your app that should not be CAS authenticated (such as an API namespace), just pass `exclude_path` to the middleware. You can pass in a string that matches the beginning of the path, a regular expression or an array of strings and regular expressions.
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
95
|
+
```ruby
|
96
|
+
use Rack::CAS, server_url: '...', exclude_path: '/api'
|
97
|
+
use Rack::CAS, server_url: '...', exclude_path: /\.json/
|
98
|
+
use Rack::CAS, server_url: '...', exclude_paths: ['/api', /\.json/]
|
99
|
+
```
|
100
100
|
The same options can be passed to `FakeCAS`.
|
101
|
-
|
102
|
-
|
103
|
-
|
101
|
+
```ruby
|
102
|
+
use Rack::FakeCAS, exclude_path: '/api'
|
103
|
+
```
|
104
104
|
Integration
|
105
105
|
===========
|
106
106
|
Your app should __return a [401 status](http://httpstatus.es/401)__ whenever a request is made that requires authentication. Rack-CAS will catch these responses and attempt to authenticate via your CAS server.
|
107
107
|
|
108
108
|
Once authentication with the CAS server has completed, Rack-CAS will set the following session variables:
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
__NOTE:__ `extra_attributes` will be an empty hash unless they've been [configured on your CAS server](
|
109
|
+
```ruby
|
110
|
+
request.session['cas']['user'] #=> johndoe
|
111
|
+
request.session['cas']['extra_attributes'] #=> { 'first_name' => 'John', 'last_name' => ... }
|
112
|
+
```
|
113
|
+
__NOTE:__ `extra_attributes` will be an empty hash unless they've been [configured on your CAS server](http://casino.rbcas.com/docs/configuration/#ldap).
|
114
114
|
|
115
115
|
Testing
|
116
116
|
=======
|
@@ -118,36 +118,36 @@ Testing
|
|
118
118
|
Controller Tests
|
119
119
|
----------------
|
120
120
|
Testing your controllers and such should be as simple as setting the session variables manually in a helper.
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
121
|
+
```ruby
|
122
|
+
def set_current_user(user)
|
123
|
+
session['cas'] = { 'user' => user.username, 'extra_attributes' => {} }
|
124
|
+
end
|
125
|
+
```
|
126
126
|
Integration Tests
|
127
127
|
-----------------
|
128
128
|
Integration testing using something like [Capybara](http://jnicklas.github.com/capybara/) is a bit trickier because the session can't be manipulated directly. So for integration tests, I recommend using the provided `Rack::FakeCAS` middleware instead of `Rack::CAS`.
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
129
|
+
```ruby
|
130
|
+
require 'rack/fake_cas'
|
131
|
+
use Rack::FakeCAS
|
132
|
+
```
|
133
133
|
In addition you can pass a Hash to configure extra attributes for predefined
|
134
134
|
usernames.
|
135
|
-
|
136
|
-
|
137
|
-
|
135
|
+
```ruby
|
136
|
+
use Rack::FakeCAS, {}, {'john' => {'name' => 'John Doe'}}
|
137
|
+
```
|
138
138
|
If you are using Rails, FakeCAS is automatically used in the test environment by default. If you would like to activate it in any other environment, add the following to the corresponding `config/environments/<env>.rb`:
|
139
|
-
|
140
|
-
|
141
|
-
|
139
|
+
```ruby
|
140
|
+
config.rack_cas.fake = true
|
141
|
+
```
|
142
142
|
You can also configure extra attribute mappings through the Rails config:
|
143
|
-
|
144
|
-
|
145
|
-
|
143
|
+
```ruby
|
144
|
+
config.rack_cas.fake_attributes = { 'john' => { 'name' => 'John Doe' } }
|
145
|
+
```
|
146
146
|
Then you can simply do the following in your integration tests in order to log in.
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
147
|
+
```ruby
|
148
|
+
visit '/restricted_path'
|
149
|
+
fill_in 'username', with: 'johndoe'
|
150
|
+
fill_in 'password', with: 'any password'
|
151
|
+
click_button 'Login'
|
152
|
+
```
|
153
153
|
__NOTE:__ The FakeCAS middleware will authenticate any username with any password and so should never be used in production.
|
data/lib/rack-cas.rb
CHANGED
@@ -0,0 +1,36 @@
|
|
1
|
+
module RackCAS
|
2
|
+
class Configuration
|
3
|
+
SETTINGS = [:server_url, :session_store, :exclude_path, :exclude_paths, :extra_attributes_filter, :verify_ssl_cert]
|
4
|
+
|
5
|
+
SETTINGS.each do |setting|
|
6
|
+
attr_accessor setting
|
7
|
+
|
8
|
+
define_method "#{setting}?" do
|
9
|
+
!(send(setting).nil? || send(setting) == [])
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@verify_ssl_cert = true
|
15
|
+
end
|
16
|
+
|
17
|
+
def extra_attributes_filter
|
18
|
+
Array(@extra_attributes_filter)
|
19
|
+
end
|
20
|
+
|
21
|
+
def update(settings_hash)
|
22
|
+
settings_hash.each do |setting, value|
|
23
|
+
unless SETTINGS.include? setting.to_sym
|
24
|
+
raise ArgumentError, "invalid setting: #{setting}"
|
25
|
+
end
|
26
|
+
|
27
|
+
self.public_send "#{setting}=", value
|
28
|
+
end
|
29
|
+
|
30
|
+
raise ArgumentError, 'server_url is required' unless server_url?
|
31
|
+
if session_store? && !session_store.respond_to?(:destroy_session_by_cas_ticket)
|
32
|
+
raise ArgumentError, 'session_store does not support single-sign-out'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -83,7 +83,10 @@ module RackCAS
|
|
83
83
|
return @response unless @response.nil?
|
84
84
|
|
85
85
|
http = Net::HTTP.new(@url.host, @url.inferred_port)
|
86
|
-
|
86
|
+
if @url.scheme == 'https'
|
87
|
+
http.use_ssl = true
|
88
|
+
http.verify_mode = RackCAS.config.verify_ssl_cert? ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
|
89
|
+
end
|
87
90
|
|
88
91
|
http.start do |conn|
|
89
92
|
@response = conn.get(@url.request_uri, REQUEST_HEADERS)
|
data/lib/rack-cas/version.rb
CHANGED
data/lib/rack/cas.rb
CHANGED
@@ -8,21 +8,15 @@ class Rack::CAS
|
|
8
8
|
|
9
9
|
def initialize(app, config={})
|
10
10
|
@app = app
|
11
|
-
@server_url = config.delete(:server_url)
|
12
|
-
@session_store = config.delete(:session_store)
|
13
|
-
@config = config || {}
|
14
11
|
|
15
|
-
|
16
|
-
if @session_store && !@session_store.respond_to?(:destroy_session_by_cas_ticket)
|
17
|
-
raise ArgumentError, 'session_store does not support single-sign-out'
|
18
|
-
end
|
12
|
+
RackCAS.config.update config
|
19
13
|
end
|
20
14
|
|
21
15
|
def call(env)
|
22
16
|
request = Rack::Request.new(env)
|
23
17
|
cas_request = CASRequest.new(request)
|
24
18
|
|
25
|
-
if cas_request.path_matches?
|
19
|
+
if cas_request.path_matches? RackCAS.config.exclude_path || RackCAS.config.exclude_paths
|
26
20
|
return @app.call(env)
|
27
21
|
end
|
28
22
|
|
@@ -48,10 +42,10 @@ class Rack::CAS
|
|
48
42
|
return redirect_to server.logout_url(request.params).to_s
|
49
43
|
end
|
50
44
|
|
51
|
-
if cas_request.single_sign_out? &&
|
45
|
+
if cas_request.single_sign_out? && RackCAS.config.session_store?
|
52
46
|
log env, 'rack-cas: Intercepting single-sign-out request.'
|
53
47
|
|
54
|
-
|
48
|
+
RackCAS.config.session_store.destroy_session_by_cas_ticket(cas_request.ticket)
|
55
49
|
return [200, {'Content-Type' => 'text/plain'}, ['CAS Single-Sign-Out request intercepted.']]
|
56
50
|
end
|
57
51
|
|
@@ -69,7 +63,7 @@ class Rack::CAS
|
|
69
63
|
protected
|
70
64
|
|
71
65
|
def server
|
72
|
-
@server ||= RackCAS::Server.new(
|
66
|
+
@server ||= RackCAS::Server.new(RackCAS.config.server_url)
|
73
67
|
end
|
74
68
|
|
75
69
|
def get_user(service_url, ticket)
|
@@ -77,10 +71,7 @@ class Rack::CAS
|
|
77
71
|
end
|
78
72
|
|
79
73
|
def store_session(request, user, ticket, extra_attrs = {})
|
80
|
-
|
81
|
-
filter = Array(@config[:extra_attributes_filter]).map(&:to_s)
|
82
|
-
extra_attrs = extra_attrs.select { |key, val| filter.include? key }
|
83
|
-
end
|
74
|
+
extra_attrs.select! { |key, val| RackCAS.config.extra_attributes_filter.map(&:to_s).include? key.to_s }
|
84
75
|
|
85
76
|
request.session['cas'] = { 'user' => user, 'ticket' => ticket, 'extra_attributes' => extra_attrs }
|
86
77
|
end
|
@@ -96,4 +87,4 @@ class Rack::CAS
|
|
96
87
|
env['rack.errors'].write(message)
|
97
88
|
end
|
98
89
|
end
|
99
|
-
end
|
90
|
+
end
|
data/lib/rack/fake_cas.rb
CHANGED
@@ -28,11 +28,15 @@ class Rack::FakeCAS
|
|
28
28
|
@request.session.clear
|
29
29
|
redirect_to "#{@request.script_name}/"
|
30
30
|
|
31
|
+
# built-in way to get to the login page without needing to return a 401 status
|
32
|
+
when '/fake_cas_login'
|
33
|
+
render_login_page
|
34
|
+
|
31
35
|
else
|
32
36
|
response = @app.call(env)
|
33
37
|
|
34
38
|
if response[0] == 401 # access denied
|
35
|
-
|
39
|
+
render_login_page
|
36
40
|
else
|
37
41
|
response
|
38
42
|
end
|
@@ -41,6 +45,10 @@ class Rack::FakeCAS
|
|
41
45
|
|
42
46
|
protected
|
43
47
|
|
48
|
+
def render_login_page
|
49
|
+
[ 200, { 'Content-Type' => 'text/html' }, [login_page] ]
|
50
|
+
end
|
51
|
+
|
44
52
|
def login_page
|
45
53
|
<<-EOS
|
46
54
|
<!doctype html>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-cas
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Crownoble
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-03-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -58,14 +58,28 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '2
|
61
|
+
version: '3.2'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '2
|
68
|
+
version: '3.2'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec-its
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: rack-test
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -101,11 +115,12 @@ extensions: []
|
|
101
115
|
extra_rdoc_files: []
|
102
116
|
files:
|
103
117
|
- MIT-LICENSE
|
104
|
-
- README.
|
118
|
+
- README.md
|
105
119
|
- lib/generators/cas_session_store_migration_generator.rb
|
106
120
|
- lib/generators/templates/migration.rb
|
107
121
|
- lib/rack-cas.rb
|
108
122
|
- lib/rack-cas/cas_request.rb
|
123
|
+
- lib/rack-cas/configuration.rb
|
109
124
|
- lib/rack-cas/railtie.rb
|
110
125
|
- lib/rack-cas/server.rb
|
111
126
|
- lib/rack-cas/service_validation_response.rb
|
@@ -147,4 +162,3 @@ signing_key:
|
|
147
162
|
specification_version: 4
|
148
163
|
summary: Rack-based CAS client
|
149
164
|
test_files: []
|
150
|
-
has_rdoc:
|