spid 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9cccde8251b49654537f88e24704de56844883d61c3e2939edf7a7b05c277850
4
- data.tar.gz: 703d39c5c631e0a988dc3b36969e1dff7aeeab8622e70a935b4c52486bd50568
3
+ metadata.gz: 960e16fa23660bf794d8569793c49f01671883612e6e96c56d9cc9ec7584c887
4
+ data.tar.gz: 18aa49e2bd0173eb7aaae0141fd199c73fc97f4f9538e04e998fd459f4406e1f
5
5
  SHA512:
6
- metadata.gz: 9025d41fdf1de349f3bc3e595eeca6eab68d8be7d26c9026a5d8aa2544e50574a75151539ad6c30e67e9cb99ce5ed1c94c1d3f9b109814cd171faa23cfe9141e
7
- data.tar.gz: 793b85a398c663be4c835ff76a4d420170f0d58e6a09bafccd98042d61cfa181718b74769f2443897f85ebef150be11b66b3f9ddc1ac6f26833ac8f14e6dffa9
6
+ metadata.gz: 294072c36735dd72f29e0b66a5d8df0118637079223faa7a9f8b71778cd2b871b639174267b775c6505d1723d1b5e4126b4e243941a6a6f9cecdf4a028c87394
7
+ data.tar.gz: 18525e552a24740ad2f51bc73f7d7e96c1f1ab583ea96372c04f6560a6df8efe7af2cb802b0631e68b61594e010f9c6790a40d8f0b17b5575207ce4fafe5bb83
data/.rubocop.yml CHANGED
@@ -30,3 +30,5 @@ Style/EmptyMethod:
30
30
  EnforcedStyle: expanded
31
31
  Style/StringLiterals:
32
32
  EnforcedStyle: double_quotes
33
+ Style/WordArray:
34
+ EnforcedStyle: brackets
data/CHANGELOG.md CHANGED
@@ -1,6 +1,23 @@
1
1
  # Changelog
2
2
 
3
3
  ## [Unreleased]
4
+
5
+ ## [0.10.0] - 2018-08-02
6
+ ### Added
7
+ - Handled Relay State in sso/slo responses
8
+ - session["spid"] initialized
9
+ - Configurable Bindings
10
+
11
+ ### Changed
12
+ - Signature in url instead of in SAMLRequest body
13
+
14
+ ### Fixed
15
+ - Metadata rack response body is now an array
16
+ - Typo on authn context comparison value
17
+ - AllowCreate is not expected in NameIDPolicy element
18
+ - Redirects to idp will not cached anymore
19
+
20
+ ## [0.9.0] - 2018-07-31
4
21
  ### Added
5
22
  - Rack middleware that handles spid login requests
6
23
  - Rack middleware that handles spid logout requests
@@ -72,7 +89,9 @@
72
89
  - Coveralls Integration
73
90
  - Rubygems version badge in README
74
91
 
75
- [Unreleased]: https://github.com/italia/spid-ruby/compare/v0.8.0...HEAD
92
+ [Unreleased]: https://github.com/italia/spid-ruby/compare/v0.10.0...HEAD
93
+ [0.10.0]: https://github.com/italia/spid-ruby/compare/v0.9.0...v0.10.0
94
+ [0.9.0]: https://github.com/italia/spid-ruby/compare/v0.8.0...v0.9.0
76
95
  [0.8.0]: https://github.com/italia/spid-ruby/compare/v0.7.0...v0.8.0
77
96
  [0.7.0]: https://github.com/italia/spid-ruby/compare/v0.6.0...v0.7.0
78
97
  [0.6.0]: https://github.com/italia/spid-ruby/compare/v0.5.0...v0.6.0
data/README.md CHANGED
@@ -16,13 +16,14 @@ Ruby library for SPID authentication
16
16
 
17
17
  Add into your Gemfile
18
18
 
19
- ```
19
+ ```ruby
20
20
  gem "ruby-saml",
21
21
  github: "davidlibrera/ruby-saml",
22
- ref: "4204afc2439f712db8909bccfd8d6e15f9320c34"
22
+ ref: "571e280031883abe3aad7c5b856353f94354fd06"
23
23
  gem "spid"
24
24
  ```
25
25
 
26
+
26
27
  ## Features
27
28
 
28
29
  |<img src="https://github.com/italia/spid-graphics/blob/master/spid-logos/spid-logo-c-lb.png?raw=true" width="100" /><br />_Compliance with [SPID regulations](http://www.agid.gov.it/sites/default/files/circolari/spid-regole_tecniche_v1.pdf) (for Service Providers)_||
@@ -6,6 +6,9 @@ module Spid
6
6
  class AuthnRequest < ::OneLogin::RubySaml::Authrequest # :nodoc:
7
7
  def create_xml_document(settings)
8
8
  original_document = super(settings)
9
+ root = original_document.elements["//samlp:AuthnRequest"]
10
+ name_id_policy_element = root.add_element("samlp:NameIDPolicy")
11
+ name_id_policy_element.attributes["Format"] = format_transient
9
12
  issuer_element = original_document.elements["//saml:Issuer"]
10
13
  issuer_element.attributes["Format"] = format_entity
11
14
  issuer_element.attributes["NameQualifier"] = settings.issuer
@@ -14,6 +17,10 @@ module Spid
14
17
 
15
18
  private
16
19
 
20
+ def format_transient
21
+ "urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
22
+ end
23
+
17
24
  def format_entity
18
25
  "urn:oasis:names:tc:SAML:2.0:nameid-format:entity"
19
26
  end
@@ -14,21 +14,27 @@ module Spid
14
14
  attr_accessor :private_key
15
15
  attr_accessor :certificate
16
16
  attr_accessor :attribute_service_name
17
+ attr_accessor :default_relay_state_path
18
+ attr_accessor :acs_binding
19
+ attr_accessor :slo_binding
17
20
 
18
21
  # rubocop:disable Metrics/MethodLength
19
22
  def initialize
20
- @idp_metadata_dir_path = "idp_metadata"
21
- @metadata_path = "/spid/metadata"
22
- @start_sso_path = "/spid/login"
23
- @start_slo_path = "/spid/logout"
24
- @acs_path = "/spid/sso"
25
- @slo_path = "/spid/slo"
26
- @digest_method = Spid::SHA256
27
- @signature_method = Spid::RSA_SHA256
28
- @attribute_service_name = attribute_service_name
29
- @hostname = nil
30
- @private_key = nil
31
- @certificate = nil
23
+ @idp_metadata_dir_path = "idp_metadata"
24
+ @metadata_path = "/spid/metadata"
25
+ @start_sso_path = "/spid/login"
26
+ @start_slo_path = "/spid/logout"
27
+ @acs_path = "/spid/sso"
28
+ @slo_path = "/spid/slo"
29
+ @digest_method = Spid::SHA256
30
+ @signature_method = Spid::RSA_SHA256
31
+ @attribute_service_name = nil
32
+ @hostname = nil
33
+ @private_key = nil
34
+ @certificate = nil
35
+ @default_relay_state_path = "/"
36
+ @acs_binding = Spid::BINDINGS_HTTP_POST
37
+ @slo_binding = Spid::BINDINGS_HTTP_REDIRECT
32
38
  end
33
39
  # rubocop:enable Metrics/MethodLength
34
40
 
data/lib/spid/metadata.rb CHANGED
@@ -17,7 +17,9 @@ module Spid
17
17
  private_key: private_key_content,
18
18
  certificate: certificate_content,
19
19
  assertion_consumer_service_url: assertion_consumer_service_url,
20
+ assertion_consumer_service_binding: Spid.configuration.acs_binding,
20
21
  single_logout_service_url: single_logout_service_url,
22
+ single_logout_service_binding: Spid.configuration.slo_binding,
21
23
  security: {
22
24
  authn_requests_signed: true,
23
25
  logout_requests_signed: false,
@@ -28,7 +28,7 @@ module Spid
28
28
 
29
29
  def response
30
30
  [
31
- 301,
31
+ 302,
32
32
  { "Location" => sso_url },
33
33
  []
34
34
  ]
@@ -36,7 +36,8 @@ module Spid
36
36
 
37
37
  def sso_url
38
38
  Spid::Sso::Request.new(
39
- idp_name: idp_name
39
+ idp_name: idp_name,
40
+ relay_state: relay_state
40
41
  ).to_saml
41
42
  end
42
43
 
@@ -49,6 +50,10 @@ module Spid
49
50
  request.path == Spid.configuration.start_sso_path
50
51
  end
51
52
 
53
+ def relay_state
54
+ request.params["relay_state"]
55
+ end
56
+
52
57
  def idp_name
53
58
  request.params["idp_name"]
54
59
  end
@@ -28,7 +28,7 @@ module Spid
28
28
 
29
29
  def response
30
30
  [
31
- 301,
31
+ 302,
32
32
  { "Location" => slo_url },
33
33
  []
34
34
  ]
@@ -37,6 +37,7 @@ module Spid
37
37
  def slo_url
38
38
  Spid::Slo::Request.new(
39
39
  idp_name: idp_name,
40
+ relay_state: relay_state,
40
41
  session_index: spid_session["session-index"]
41
42
  ).to_saml
42
43
  end
@@ -52,12 +53,11 @@ module Spid
52
53
  end
53
54
 
54
55
  def spid_session
55
- rack_session["spid"] unless rack_session.nil?
56
+ request.session["spid"]
56
57
  end
57
58
 
58
- def rack_session
59
- return if request.has_header?("rack.session").nil?
60
- request.get_header("rack.session")
59
+ def relay_state
60
+ request.params["relay_state"]
61
61
  end
62
62
 
63
63
  def idp_name
@@ -33,7 +33,7 @@ module Spid
33
33
  [
34
34
  200,
35
35
  { "Content-Type" => "application/xml" },
36
- metadata.to_xml
36
+ [metadata.to_xml]
37
37
  ]
38
38
  end
39
39
 
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spid
4
+ class Rack
5
+ class Session # :nodoc:
6
+ attr_reader :app
7
+
8
+ def initialize(app)
9
+ @app = app
10
+ end
11
+
12
+ def call(env)
13
+ request = ::Rack::Request.new(env)
14
+ request.session["spid"] ||= {}
15
+ app.call(env)
16
+ end
17
+ end
18
+ end
19
+ end
data/lib/spid/rack/slo.rb CHANGED
@@ -11,8 +11,11 @@ module Spid
11
11
 
12
12
  def call(env)
13
13
  @slo = SloEnv.new(env)
14
- env["rack.session"].delete("spid") if @slo.valid_request?
15
- app.call(env)
14
+ if @slo.valid_request?
15
+ @slo.response
16
+ else
17
+ app.call(env)
18
+ end
16
19
  end
17
20
 
18
21
  class SloEnv # :nodoc:
@@ -24,9 +27,49 @@ module Spid
24
27
  @request = ::Rack::Request.new(env)
25
28
  end
26
29
 
27
- def valid_request?
30
+ def clear_session
31
+ request.session["spid"] = {}
32
+ end
33
+
34
+ def response
35
+ clear_session
36
+ [
37
+ 302,
38
+ { "Location" => relay_state },
39
+ []
40
+ ]
41
+ end
42
+
43
+ def relay_state
44
+ if !request.params["RelayState"].nil? &&
45
+ request.params["RelayState"] != ""
46
+ request.params["RelayState"]
47
+ else
48
+ Spid.configuration.default_relay_state_path
49
+ end
50
+ end
51
+
52
+ def valid_get?
53
+ request.get? &&
54
+ Spid.configuration.slo_binding == Spid::BINDINGS_HTTP_REDIRECT
55
+ end
56
+
57
+ def valid_post?
58
+ request.post? &&
59
+ Spid.configuration.slo_binding == Spid::BINDINGS_HTTP_POST
60
+ end
61
+
62
+ def valid_http_verb?
63
+ valid_post? || valid_get?
64
+ end
65
+
66
+ def valid_path?
28
67
  request.path == Spid.configuration.slo_path
29
68
  end
69
+
70
+ def valid_request?
71
+ valid_path? && valid_http_verb?
72
+ end
30
73
  end
31
74
  end
32
75
  end
data/lib/spid/rack/sso.rb CHANGED
@@ -13,13 +13,10 @@ module Spid
13
13
  @sso = SsoEnv.new(env)
14
14
 
15
15
  if @sso.valid_request?
16
- response = @sso.sso_response
17
- env["rack.session"]["spid"] = {
18
- "attributes" => response.attributes,
19
- "session_index" => response.session_index
20
- }
16
+ @sso.response
17
+ else
18
+ app.call(env)
21
19
  end
22
- app.call(env)
23
20
  end
24
21
 
25
22
  class SsoEnv # :nodoc:
@@ -31,14 +28,57 @@ module Spid
31
28
  @request = ::Rack::Request.new(env)
32
29
  end
33
30
 
31
+ def store_session
32
+ request.session["spid"] = {
33
+ "attributes" => sso_response.attributes,
34
+ "session_index" => sso_response.session_index
35
+ }
36
+ end
37
+
38
+ def response
39
+ store_session
40
+ [
41
+ 302,
42
+ { "Location" => relay_state },
43
+ []
44
+ ]
45
+ end
46
+
34
47
  def saml_response
35
48
  request.params["SAMLResponse"]
36
49
  end
37
50
 
38
- def valid_request?
51
+ def relay_state
52
+ if !request.params["RelayState"].nil? &&
53
+ request.params["RelayState"] != ""
54
+ request.params["RelayState"]
55
+ else
56
+ Spid.configuration.default_relay_state_path
57
+ end
58
+ end
59
+
60
+ def valid_get?
61
+ request.get? &&
62
+ Spid.configuration.acs_binding == Spid::BINDINGS_HTTP_REDIRECT
63
+ end
64
+
65
+ def valid_post?
66
+ request.post? &&
67
+ Spid.configuration.acs_binding == Spid::BINDINGS_HTTP_POST
68
+ end
69
+
70
+ def valid_http_verb?
71
+ valid_get? || valid_post?
72
+ end
73
+
74
+ def valid_path?
39
75
  request.path == Spid.configuration.acs_path
40
76
  end
41
77
 
78
+ def valid_request?
79
+ valid_path? && valid_http_verb?
80
+ end
81
+
42
82
  def sso_response
43
83
  ::Spid::Sso::Response.new(body: saml_response)
44
84
  end
data/lib/spid/rack.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "rack/builder"
4
+ require "spid/rack/session"
4
5
  require "spid/rack/login"
5
6
  require "spid/rack/logout"
6
7
  require "spid/rack/sso"
@@ -13,6 +14,7 @@ module Spid
13
14
 
14
15
  def initialize(app)
15
16
  @app = ::Rack::Builder.new do
17
+ use Spid::Rack::Session
16
18
  use Spid::Rack::Metadata
17
19
  use Spid::Rack::Login
18
20
  use Spid::Rack::Logout
@@ -62,7 +62,7 @@ module Spid
62
62
  certificate: certificate,
63
63
  security: {
64
64
  authn_requests_signed: true,
65
- embed_sign: true,
65
+ embed_sign: false,
66
66
  digest_method: digest_method,
67
67
  signature_method: signature_method
68
68
  }
@@ -81,7 +81,7 @@ module Spid
81
81
  certificate: certificate,
82
82
  security: {
83
83
  logout_requests_signed: true,
84
- embed_sign: true,
84
+ embed_sign: false,
85
85
  digest_method: digest_method,
86
86
  signature_method: signature_method
87
87
  }
@@ -8,14 +8,22 @@ module Spid
8
8
  class Request # :nodoc:
9
9
  attr_reader :idp_name
10
10
  attr_reader :session_index
11
+ attr_reader :relay_state
11
12
 
12
- def initialize(idp_name:, session_index:)
13
+ def initialize(idp_name:, session_index:, relay_state: nil)
13
14
  @idp_name = idp_name
14
15
  @session_index = session_index
16
+ @relay_state =
17
+ begin
18
+ relay_state || Spid.configuration.default_relay_state_path
19
+ end
15
20
  end
16
21
 
17
22
  def to_saml
18
- logout_request.create(saml_settings)
23
+ logout_request.create(
24
+ saml_settings,
25
+ "RelayState" => relay_state
26
+ )
19
27
  end
20
28
 
21
29
  def saml_settings
@@ -7,16 +7,29 @@ module Spid
7
7
  module Sso
8
8
  class Request # :nodoc:
9
9
  attr_reader :idp_name
10
+ attr_reader :relay_state
10
11
  attr_reader :authn_context
11
12
  attr_reader :authn_context_comparison
12
13
 
13
- def initialize(idp_name:, authn_context: Spid::L1)
14
+ def initialize(
15
+ idp_name:,
16
+ relay_state: nil,
17
+ authn_context: nil
18
+ )
14
19
  @idp_name = idp_name
15
- @authn_context = authn_context
20
+ @relay_state = relay_state
21
+ @authn_context = authn_context || Spid::L1
22
+ @relay_state =
23
+ begin
24
+ relay_state || Spid.configuration.default_relay_state_path
25
+ end
16
26
  end
17
27
 
18
28
  def to_saml
19
- authn_request.create(saml_settings)
29
+ authn_request.create(
30
+ saml_settings,
31
+ "RelayState" => relay_state
32
+ )
20
33
  end
21
34
 
22
35
  def saml_settings
@@ -40,7 +40,6 @@ module Spid
40
40
  def inner_sso_attributes
41
41
  {
42
42
  protocol_binding: protocol_binding_value,
43
- name_identifier_format: name_identifier_format_value,
44
43
  authn_context: authn_context,
45
44
  authn_context_comparison: Spid::MINIMUM_COMPARISON
46
45
  }
@@ -58,10 +57,6 @@ module Spid
58
57
  def protocol_binding_value
59
58
  "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
60
59
  end
61
-
62
- def name_identifier_format_value
63
- "urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
64
- end
65
60
  end
66
61
  end
67
62
  end
data/lib/spid/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Spid
4
- VERSION = "0.9.0"
4
+ VERSION = "0.10.0"
5
5
  end
data/lib/spid.rb CHANGED
@@ -19,10 +19,13 @@ module Spid # :nodoc:
19
19
  class UnknownSignatureMethodError < StandardError; end
20
20
 
21
21
  EXACT_COMPARISON = :exact
22
- MINIMUM_COMPARISON = :minumum
22
+ MINIMUM_COMPARISON = :minimum
23
23
  BETTER_COMPARISON = :better
24
24
  MAXIMUM_COMPARISON = :maximum
25
25
 
26
+ BINDINGS_HTTP_POST = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
27
+ BINDINGS_HTTP_REDIRECT = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
28
+
26
29
  COMPARISON_METHODS = [
27
30
  EXACT_COMPARISON,
28
31
  MINIMUM_COMPARISON,
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Librera
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-31 00:00:00.000000000 Z
11
+ date: 2018-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -313,6 +313,7 @@ files:
313
313
  - lib/spid/rack/login.rb
314
314
  - lib/spid/rack/logout.rb
315
315
  - lib/spid/rack/metadata.rb
316
+ - lib/spid/rack/session.rb
316
317
  - lib/spid/rack/slo.rb
317
318
  - lib/spid/rack/sso.rb
318
319
  - lib/spid/service_provider.rb