saml_camel 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5ae86d2afccc6e4f06cecbce01cb9c8e7b26340
|
4
|
+
data.tar.gz: 200725807b56d5a93dd488edd9ac18bdd1a5006b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b665b05d63a9f28fa45f79b48067de8e18daebb9f530223174b48195e676ebd08abf984a853a11c7fc1c61cd0db354098bba25a9db47da0b49136c70b55ebcb
|
7
|
+
data.tar.gz: e13b5b41e5d628f99a75da7be03b06d2671ea60d26e3fc5280aa07be80b43245ae9dc63303878bffbdcedc90183c19e43650caa667ae209955bcd240adeb1f6d
|
data/README.md
CHANGED
@@ -16,20 +16,21 @@ $ bundle
|
|
16
16
|
## Usage
|
17
17
|
### IMPORTANT: This step enables security features and is required to use the gem!
|
18
18
|
1. in your environments config (`config/development.rb` for example) ensure that you have caching configured as follows
|
19
|
-
|
19
|
+
|
20
|
+
**NOTE:** use ths cache_store most appropriate for your situation. It may make more sense to use a file store, or a redis server
|
20
21
|
```ruby
|
21
22
|
config.action_controller.perform_caching = true
|
22
23
|
config.cache_store = :memory_store
|
23
24
|
```
|
24
25
|
|
25
|
-
|
26
|
+
2. run `rake saml_camel:generate_saml` to generate metadata files for each environment. you can also specify a custom environment like this `rake saml_camel:generate_saml environment=acceptance`
|
26
27
|
|
27
|
-
**Note: these steps will use development as an example, if you use separate metadata per environment, you will repeat each step for your chosen environment**
|
28
|
+
**Note: these steps will use development as an example, if you use separate metadata per environment, you will repeat each step for your chosen environment**
|
28
29
|
|
29
|
-
|
30
|
+
3. from the root of your app open `saml/development/settings.json` and specify an entity ID of your choice. this is a unique identifier used by the
|
30
31
|
Identity Provider(idp) to recognize your app. Typically it should take the form of a url, however note that it is just an identifier and does not have to resolve (e.g. https://my-app-name/not/a/real/route)
|
31
32
|
|
32
|
-
|
33
|
+
4. Go to https://authentication.oit.duke.edu/manager/register/sp and register your metadata with the identity provider. You will need the values from `saml/development/settings.json` in addition to the `saml/development/saml_certificate.crt`
|
33
34
|
|
34
35
|
- copy the entity_id you chose in the `settings.json` file and paste it into the "Entity Field"
|
35
36
|
- fill out functional purpose, responsible dept, function owner dept, and audience with information relevant to your application
|
@@ -37,38 +38,71 @@ Identity Provider(idp) to recognize your app. Typically it should take the form
|
|
37
38
|
- copy the acs value and paste it into the Location field in the Assertion Consumer Service box
|
38
39
|
- note that the default host value for ACS is `http://locahost:3000` which is the default `rails s` host. If you're using a differnet host (such as in production or using docker) you will want to replace the host value with what is relevent for your situation(*e.g. https://my-app.duke.edu/saml/consumeSaml*), but keep the path `/saml/consumeSaml`
|
39
40
|
|
40
|
-
|
41
|
-
```ruby
|
42
|
-
mount SamlCamel::Engine, at: "/saml"
|
43
|
-
```
|
44
|
-
|
41
|
+
5. In your app mount the engine in config/routes.rb
|
42
|
+
```ruby
|
43
|
+
mount SamlCamel::Engine, at: "/saml"
|
44
|
+
```
|
45
45
|
|
46
46
|
6. now simply provide the `saml_protect` method in your controllers (via `before_action`) to protect paths
|
47
47
|
```ruby
|
48
|
-
class DashboardController < ApplicationController
|
49
|
-
|
48
|
+
class DashboardController < ApplicationController
|
49
|
+
before_action :saml_protect, except: [:home]
|
50
50
|
|
51
|
-
|
52
|
-
|
51
|
+
def home
|
52
|
+
end
|
53
53
|
|
54
|
-
|
54
|
+
def index
|
55
|
+
end
|
55
56
|
end
|
56
|
-
|
57
|
-
end
|
58
57
|
```
|
59
58
|
|
60
|
-
|
61
59
|
7. to logout simply make a post to `localhost:3000/saml/logout`. This will kill the local saml session, and the session with the identity provider.
|
62
60
|
|
63
61
|
7. response attributes found in `session[:saml_attributes]`
|
62
|
+
*note that the session can not store over the 4 kilobyte limit. Keep
|
63
|
+
this in mind in the use case of requesting a significant amount of attributes*
|
64
64
|
|
65
65
|
8. It is recommended to set `config.force_ssl = true` in the `config/environments/production.rb` file for security
|
66
66
|
|
67
|
-
|
68
67
|
9. Logging is turned on by default. Logging is configured in `saml/development/settings.json`. To utilize logging saml_logging should be set to true (default), and primary_id must have a value. primary_id is the saml attribute you consider to be a primary identifier for a user
|
69
68
|
|
70
69
|
10. Users can go to http://localhost:3000/saml/attributes to view attributes being passed through
|
71
70
|
|
71
|
+
## Example settings.json
|
72
|
+
```json
|
73
|
+
{
|
74
|
+
"_comment": "note you will need to restart the application when you make changes to this file",
|
75
|
+
"settings": {
|
76
|
+
"acs": "http://localhost:3000/saml/consumeSaml",
|
77
|
+
"entity_id": "http://my-entity-id.corgi",
|
78
|
+
"sso_url": "https://shib.oit.duke.edu/idp/profile/SAML2/Redirect/SSO",
|
79
|
+
"logout_return_url": "http://localhost:3000",
|
80
|
+
"primary_id": "eduPersonPrincipalName",
|
81
|
+
"saml_logging": true
|
82
|
+
},
|
83
|
+
"attribute_map": {
|
84
|
+
"urn:oid:1.3.6.1.4.1.5923.1.1.1.9": "eduPersonScopedAffiliation",
|
85
|
+
"urn:oid:1.3.6.1.4.1.5923.1.1.1.6": "eduPersonPrincipalName",
|
86
|
+
"urn:oid:2.5.4.3": "cn",
|
87
|
+
"urn:oid:0.9.2342.19200300.100.1.1": "uid",
|
88
|
+
"urn:oid:0.9.2342.19200300.100.1.3": "mail",
|
89
|
+
"urn:oid:1.3.6.1.4.1.5923.1.1.1.5": "eduPersonPrimaryAffiliation",
|
90
|
+
"urn:oid:2.16.840.1.113730.3.1.241": "displayName",
|
91
|
+
"urn:mace:duke.edu:idms:unique-id": "duDukeID",
|
92
|
+
"urn:mace:duke.edu:idms:dku-id": "dku-id",
|
93
|
+
"urn:oid:1.3.6.1.4.1.5923.1.5.1.1": "isMemberOf",
|
94
|
+
"urn:oid:2.5.4.42": "givenName",
|
95
|
+
"urn:oid:2.5.4.4": "sn",
|
96
|
+
"urn:oid:2.5.4.11": "ou",
|
97
|
+
"urn:oid:1.3.6.1.4.1.5923.1.1.1.1": "eduPersonAffiliation",
|
98
|
+
"urn:oid:2.5.4.20": "telephoneNumber",
|
99
|
+
"urn:oid:2.5.4.12": "title",
|
100
|
+
"urn:mace:duke.edu:idms:middle-name1": "duMiddleName1",
|
101
|
+
"urn:mace:duke.edu:idms:proxy-token": "duProxyToken"
|
102
|
+
}
|
103
|
+
}
|
104
|
+
```
|
105
|
+
|
72
106
|
|
73
107
|
## License
|
74
108
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
@@ -7,11 +7,12 @@ module SamlCamel::SamlHelpers
|
|
7
7
|
|
8
8
|
#this generates a call to the idp, which will then be returned to the consume action the in saml_contorller
|
9
9
|
def saml_request(host_request)
|
10
|
-
relay_state = SecureRandom.base64.chomp.gsub( /\
|
10
|
+
relay_state = SecureRandom.base64.chomp.gsub( /\W/, '' ) #set relay state to secure against replay attack
|
11
11
|
request = OneLogin::RubySaml::Authrequest.new
|
12
12
|
|
13
13
|
#store relay state, ip address and original url request in memory to be used for verification and redirect after response
|
14
|
-
|
14
|
+
assign_permit_key
|
15
|
+
permit_key = session[:saml_session_id].to_sym
|
15
16
|
Rails.cache.fetch(permit_key, expires_in: 5.minutes) do
|
16
17
|
{ip_address: host_request.remote_ip, relay_state: relay_state, redirect_url: host_request.url }
|
17
18
|
end
|
@@ -22,7 +23,7 @@ module SamlCamel::SamlHelpers
|
|
22
23
|
|
23
24
|
#validates the user ip address and relay state given to IDP. Prevents Replay Attacks.
|
24
25
|
def valid_state(param_relay_state, remote_ip)
|
25
|
-
permit_key = session[:
|
26
|
+
permit_key = session[:saml_session_id].to_sym
|
26
27
|
saml_cache = Rails.cache.fetch(permit_key)
|
27
28
|
stored_relay = saml_cache[:relay_state]
|
28
29
|
stored_ip = saml_cache[:ip_address]
|
@@ -52,4 +53,8 @@ module SamlCamel::SamlHelpers
|
|
52
53
|
session[:saml_success] = nil
|
53
54
|
end
|
54
55
|
|
56
|
+
def assign_permit_key
|
57
|
+
session[:saml_session_id] = SecureRandom.base64.chomp.gsub( /\W/, '' )
|
58
|
+
end
|
59
|
+
|
55
60
|
end
|
@@ -16,13 +16,13 @@ module SamlCamel
|
|
16
16
|
#consumes the saml response from the IDP
|
17
17
|
def consume
|
18
18
|
raise "Invalid RelayState" unless valid_state(params[:RelayState], request.remote_ip)
|
19
|
-
permit_key = session[:
|
19
|
+
permit_key = session[:saml_session_id].to_sym
|
20
20
|
redirect_path = Rails.cache.fetch(permit_key)[:redirect_url]
|
21
21
|
Rails.cache.delete(permit_key) #we no longer need cache at this stage
|
22
|
+
session[:saml_session_id] = nil
|
22
23
|
|
23
24
|
response = OneLogin::RubySaml::Response.new(params[:SAMLResponse], :settings => saml_settings)
|
24
25
|
response.settings = saml_settings
|
25
|
-
|
26
26
|
if response.is_valid? # validate the SAML Response
|
27
27
|
# authorize_success, log the user
|
28
28
|
session[:saml_success] = true
|
@@ -31,11 +31,11 @@ module SamlCamel
|
|
31
31
|
session[:saml_attributes] = SamlCamel::Transaction.map_attributes(response.attributes)
|
32
32
|
SamlCamel::Logging.successfull_auth(session[:saml_attributes])
|
33
33
|
|
34
|
-
|
35
34
|
redirect_to redirect_path
|
36
35
|
else # otherwise list out the errors in the response
|
37
|
-
permit_key = session[:
|
36
|
+
permit_key = session[:saml_session_id].to_sym
|
38
37
|
Rails.cache.delete(permit_key)
|
38
|
+
session[:saml_session_id] = nil
|
39
39
|
|
40
40
|
session[:saml_success] = false
|
41
41
|
response.errors
|
@@ -44,9 +44,10 @@ module SamlCamel
|
|
44
44
|
redirect_to action: "failure", locals:{errors: response.errors}
|
45
45
|
end
|
46
46
|
rescue => e
|
47
|
-
permit_key = session[:
|
47
|
+
permit_key = session[:saml_session_id].to_sym
|
48
48
|
Rails.cache.delete(permit_key)
|
49
49
|
session[:saml_success] = false
|
50
|
+
session[:saml_session_id] = nil
|
50
51
|
|
51
52
|
SamlCamel::Logging.auth_failure(e)
|
52
53
|
redirect_to action: "failure", locals:{errors: e}
|
@@ -64,7 +65,6 @@ module SamlCamel
|
|
64
65
|
SamlCamel::Logging.logout(session[:saml_attributes])
|
65
66
|
session[:saml_attributes] = nil
|
66
67
|
session[:sp_session] = nil
|
67
|
-
cookies.delete :saml_camel_timestamp
|
68
68
|
|
69
69
|
# return_url = SamlCamel::Transaction.logout #this methods logs the user out of the IDP, and returns a url to be redirected to
|
70
70
|
redirect_to "https://shib.oit.duke.edu/cgi-bin/logout.pl"
|
data/lib/saml_camel/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: saml_camel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- 'Danai Adkisson '
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-04-
|
11
|
+
date: 2018-04-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|