spid 0.9.0 → 0.10.0

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
  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