spid 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +15 -2
- data/CHANGELOG.md +18 -0
- data/README.md +94 -1
- data/lib/spid/authn_request.rb +67 -0
- data/lib/spid/onelogin_extension.rb +23 -0
- data/lib/spid/version.rb +1 -1
- data/lib/spid.rb +25 -0
- data/spid.gemspec +5 -0
- metadata +61 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8bfca421b316c9cb55e172e5eefc1c1acff12376dbb74716c5c3dbee76d316cd
|
4
|
+
data.tar.gz: 7ec28aa7150994bdc8d7e8e2f49161707d55de55a7099b4e910feaca9a700513
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fad0ca14fa9fb3c7de38439dce599dd736fc654537e2503c326ec73611bb7779e451a2ea90c51c3dd24938f638940bdc14a7bf67a970031184cfff072a3ec930
|
7
|
+
data.tar.gz: 86e1822001f127add77c36b3feb27656ab3899b10db2a3a074f6891cc1d257e665d33c02635be31525d90b58922e8af4cd3d5ad3d68e44cafb8475970d503535
|
data/.rubocop.yml
CHANGED
@@ -1,5 +1,18 @@
|
|
1
|
+
require: rubocop-rspec
|
2
|
+
|
1
3
|
AllCops:
|
2
|
-
|
4
|
+
Exclude:
|
5
|
+
- bin/stubs/*
|
6
|
+
TargetRubyVersion: 2.3
|
3
7
|
|
8
|
+
Layout/DotPosition:
|
9
|
+
EnforcedStyle: trailing
|
10
|
+
Metrics/BlockLength:
|
11
|
+
Exclude:
|
12
|
+
- spec/**/*.rb
|
13
|
+
RSpec/NestedGroups:
|
14
|
+
Enabled: false
|
15
|
+
Style/EmptyMethod:
|
16
|
+
EnforcedStyle: expanded
|
4
17
|
Style/StringLiterals:
|
5
|
-
EnforcedStyle:
|
18
|
+
EnforcedStyle: double_quotes
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## [Unreleased]
|
4
|
+
|
5
|
+
## [0.2.0] - 2018-07-02
|
6
|
+
### Added
|
7
|
+
- Feature table in README
|
8
|
+
- Spid::AuthnRequest create a SAML AuthnRequest specific for SPID
|
9
|
+
- Added CHANGELOG.md
|
10
|
+
|
11
|
+
## 0.1.1 - 2018-06-27
|
12
|
+
### Added
|
13
|
+
- TravisCI Integration
|
14
|
+
- Coveralls Integration
|
15
|
+
- Rubygems version badge in README
|
16
|
+
|
17
|
+
[Unreleased]: https://github.com/italia/spid-ruby/compare/v0.0.2...HEAD
|
18
|
+
[0.2.0]: https://github.com/italia/spid-ruby/compare/v0.1.1...v0.2.0
|
data/README.md
CHANGED
@@ -1,2 +1,95 @@
|
|
1
|
-
# spid-ruby
|
1
|
+
# spid-ruby
|
2
|
+
|
2
3
|
Ruby library for SPID authentication
|
4
|
+
|
5
|
+
| Project | Spid Ruby |
|
6
|
+
| ---------------------- | ------------ |
|
7
|
+
| Gem name | spid |
|
8
|
+
| License | [MIT](https://github.com/italia/spid-ruby/blob/master/LICENSE) |
|
9
|
+
| Version | [![Gem Version](https://badge.fury.io/rb/spid.svg)](http://badge.fury.io/rb/spid) |
|
10
|
+
| Continuous integration | [![Build Status](https://secure.travis-ci.org/italia/spid-ruby.svg?branch=master)](https://travis-ci.org/italia/spid-ruby) |
|
11
|
+
| Test coverage | [![Coverage Status](https://coveralls.io/repos/italia/spid-ruby/badge.svg)](https://coveralls.io/r/italia/spid-ruby) |
|
12
|
+
| Credits | [Contributors](https://github.com/italia/spid-ruby/graphs/contributors) |
|
13
|
+
|
14
|
+
## Features
|
15
|
+
|
16
|
+
|<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)_||
|
17
|
+
|:---|:---|
|
18
|
+
|**Metadata:**||
|
19
|
+
|parsing of IdP XML metadata (1.2.2.4)||
|
20
|
+
|parsing of AA XML metadata (2.2.4)||
|
21
|
+
|SP XML metadata generation (1.3.2)||
|
22
|
+
|**AuthnRequest generation (1.2.2.1):**||
|
23
|
+
|generation of AuthnRequest XML|✓|
|
24
|
+
|HTTP-Redirect binding||
|
25
|
+
|HTTP-POST binding|✓|
|
26
|
+
|`AssertionConsumerServiceURL` customization||
|
27
|
+
|`AssertionConsumerServiceIndex` customization||
|
28
|
+
|`AttributeConsumingServiceIndex` customization||
|
29
|
+
|`AuthnContextClassRef` (SPID level) customization||
|
30
|
+
|`RequestedAuthnContext/@Comparison` customization||
|
31
|
+
|`RelayState` customization (1.2.2)||
|
32
|
+
|**Response/Assertion parsing**||
|
33
|
+
|verification of `Response/Signature` value (if any)||
|
34
|
+
|verification of `Response/Signature` certificate (if any) against IdP/AA metadata||
|
35
|
+
|verification of `Assertion/Signature` value||
|
36
|
+
|verification of `Assertion/Signature` certificate against IdP/AA metadata||
|
37
|
+
|verification of `SubjectConfirmationData/@Recipient`||
|
38
|
+
|verification of `SubjectConfirmationData/@NotOnOrAfter`||
|
39
|
+
|verification of `SubjectConfirmationData/@InResponseTo`||
|
40
|
+
|verification of `Issuer`||
|
41
|
+
|verification of `Destination`||
|
42
|
+
|verification of `Conditions/@NotBefore`||
|
43
|
+
|verification of `Conditions/@NotOnOrAfter`||
|
44
|
+
|verification of `Audience`||
|
45
|
+
|parsing of Response with no `Assertion` (authentication/query failure)||
|
46
|
+
|parsing of failure `StatusCode` (Requester/Responder)||
|
47
|
+
|**Response/Assertion parsing for SSO (1.2.1, 1.2.2.2, 1.3.1):**||
|
48
|
+
|parsing of `NameID`||
|
49
|
+
|parsing of `AuthnContextClassRef` (SPID level)||
|
50
|
+
|parsing of attributes||
|
51
|
+
|**Response/Assertion parsing for attribute query (2.2.2.2, 2.3.1):**||
|
52
|
+
|parsing of attributes||
|
53
|
+
|**LogoutRequest generation (for SP-initiated logout):**||
|
54
|
+
|generation of LogoutRequest XML||
|
55
|
+
|HTTP-Redirect binding||
|
56
|
+
|HTTP-POST binding||
|
57
|
+
|**LogoutResponse parsing (for SP-initiated logout):**||
|
58
|
+
|parsing of LogoutResponse XML||
|
59
|
+
|verification of `Response/Signature` value (if any)||
|
60
|
+
|verification of `Response/Signature` certificate (if any) against IdP metadata||
|
61
|
+
|verification of `Issuer`||
|
62
|
+
|verification of `Destination`||
|
63
|
+
|PartialLogout detection||
|
64
|
+
|**LogoutRequest parsing (for third-party-initiated logout):**||
|
65
|
+
|parsing of LogoutRequest XML||
|
66
|
+
|verification of `Response/Signature` value (if any)||
|
67
|
+
|verification of `Response/Signature` certificate (if any) against IdP metadata||
|
68
|
+
|verification of `Issuer`||
|
69
|
+
|verification of `Destination`||
|
70
|
+
|parsing of `NameID`||
|
71
|
+
|**LogoutResponse generation (for third-party-initiated logout):**||
|
72
|
+
|generation of LogoutResponse XML||
|
73
|
+
|HTTP-Redirect binding||
|
74
|
+
|HTTP-POST binding||
|
75
|
+
|PartialLogout customization||
|
76
|
+
|**AttributeQuery generation (2.2.2.1):**||
|
77
|
+
|generation of AttributeQuery XML||
|
78
|
+
|SOAP binding (client)||
|
79
|
+
|
80
|
+
|<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 Attribute Authorities)_||
|
81
|
+
|:---|:---|
|
82
|
+
|**Metadata:**||
|
83
|
+
|parsing of SP XML metadata (1.3.2)||
|
84
|
+
|AA XML metadata generation (2.2.4)||
|
85
|
+
|**AttributeQuery parsing (2.2.2.1):**||
|
86
|
+
|parsing of AttributeQuery XML||
|
87
|
+
|verification of `Signature` value||
|
88
|
+
|verification of `Signature` certificate against SP metadata||
|
89
|
+
|verification of `Issuer`||
|
90
|
+
|verification of `Destination`||
|
91
|
+
|parsing of `Subject/NameID`||
|
92
|
+
|parsing of requested attributes||
|
93
|
+
|**Response/Assertion generation (2.2.2.2):**||
|
94
|
+
|generation of `Response/Assertion` XML||
|
95
|
+
|Signature||
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "onelogin/ruby-saml/authrequest"
|
4
|
+
require "spid/onelogin_extension"
|
5
|
+
require "onelogin/ruby-saml/settings"
|
6
|
+
|
7
|
+
module Spid
|
8
|
+
class AuthnRequest # :nodoc:
|
9
|
+
using OneLoginExtension
|
10
|
+
|
11
|
+
attr_reader :authn_request_attributes
|
12
|
+
|
13
|
+
# rubocop:disable Metrics/MethodLength
|
14
|
+
def initialize(
|
15
|
+
idp_sso_target_url:,
|
16
|
+
assertion_consumer_service_url:,
|
17
|
+
issuer:,
|
18
|
+
authn_context: Spid::L1,
|
19
|
+
authn_context_comparison: Spid::EXACT_COMPARISON
|
20
|
+
)
|
21
|
+
|
22
|
+
unless AUTHN_CONTEXTS.include?(authn_context)
|
23
|
+
raise Spid::UnknownAuthnContextError,
|
24
|
+
"Provided authn_context is not valid:" \
|
25
|
+
" use one of #{AUTHN_CONTEXTS.join(', ')}"
|
26
|
+
end
|
27
|
+
|
28
|
+
unless COMPARISON_METHODS.include?(authn_context_comparison)
|
29
|
+
raise Spid::UnknownAuthnComparisonMethodError,
|
30
|
+
"Provided authn_context_comparison_method is not valid:" \
|
31
|
+
" use one of #{COMPARISON_METHODS.join(', ')}"
|
32
|
+
end
|
33
|
+
|
34
|
+
@authn_request_attributes = {
|
35
|
+
idp_sso_target_url: idp_sso_target_url,
|
36
|
+
assertion_consumer_service_url: assertion_consumer_service_url,
|
37
|
+
protocol_binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
|
38
|
+
issuer: issuer,
|
39
|
+
name_identifier_format: name_identifier_format,
|
40
|
+
authn_context: authn_context,
|
41
|
+
authn_context_comparison: authn_context_comparison
|
42
|
+
}
|
43
|
+
|
44
|
+
return if authn_context <= Spid::L1
|
45
|
+
@authn_request_attributes[:force_authn] = true
|
46
|
+
end
|
47
|
+
# rubocop:enable Metrics/MethodLength
|
48
|
+
|
49
|
+
def to_xml
|
50
|
+
authn_request.create_xml_document(saml_settings)
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def name_identifier_format
|
56
|
+
"urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
|
57
|
+
end
|
58
|
+
|
59
|
+
def authn_request
|
60
|
+
::OneLogin::RubySaml::Authrequest.new
|
61
|
+
end
|
62
|
+
|
63
|
+
def saml_settings
|
64
|
+
::OneLogin::RubySaml::Settings.new authn_request_attributes
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "onelogin/ruby-saml/authrequest"
|
4
|
+
|
5
|
+
module Spid
|
6
|
+
module OneLoginExtension # :nodoc:
|
7
|
+
refine ::OneLogin::RubySaml::Authrequest do
|
8
|
+
def create_xml_document(settings)
|
9
|
+
original_document = super(settings)
|
10
|
+
issuer_element = original_document.elements["//saml:Issuer"]
|
11
|
+
issuer_element.attributes["Format"] = format_entity
|
12
|
+
issuer_element.attributes["NameQualifier"] = settings.issuer
|
13
|
+
original_document
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def format_entity
|
19
|
+
"urn:oasis:names:tc:SAML:2.0:nameid-format:entity"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/spid/version.rb
CHANGED
data/lib/spid.rb
CHANGED
@@ -1,6 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "spid/authn_request"
|
3
4
|
require "spid/version"
|
4
5
|
|
5
6
|
module Spid # :nodoc:
|
7
|
+
class UnknownAuthnComparisonMethodError < StandardError; end
|
8
|
+
class UnknownAuthnContextError < StandardError; end
|
9
|
+
|
10
|
+
EXACT_COMPARISON = :exact
|
11
|
+
MININUM_COMPARISON = :minumum
|
12
|
+
BETTER_COMPARISON = :better
|
13
|
+
MAXIMUM_COMPARISON = :maximum
|
14
|
+
|
15
|
+
COMPARISON_METHODS = [
|
16
|
+
EXACT_COMPARISON,
|
17
|
+
MININUM_COMPARISON,
|
18
|
+
BETTER_COMPARISON,
|
19
|
+
MAXIMUM_COMPARISON
|
20
|
+
].freeze
|
21
|
+
|
22
|
+
L1 = "urn:oasis:names:tc:SAML:2.0:ac:classes:SpidL1"
|
23
|
+
L2 = "urn:oasis:names:tc:SAML:2.0:ac:classes:SpidL2"
|
24
|
+
L3 = "urn:oasis:names:tc:SAML:2.0:ac:classes:SpidL3"
|
25
|
+
|
26
|
+
AUTHN_CONTEXTS = [
|
27
|
+
L1,
|
28
|
+
L2,
|
29
|
+
L3
|
30
|
+
].freeze
|
6
31
|
end
|
data/spid.gemspec
CHANGED
@@ -18,10 +18,15 @@ Gem::Specification.new do |spec|
|
|
18
18
|
|
19
19
|
spec.required_ruby_version = ">= 2.3.0"
|
20
20
|
|
21
|
+
spec.add_runtime_dependency "ruby-saml", "~> 1.8.0"
|
22
|
+
|
21
23
|
spec.add_development_dependency "bundler", "~> 1.16"
|
22
24
|
spec.add_development_dependency "bundler-audit"
|
23
25
|
spec.add_development_dependency "coveralls"
|
26
|
+
spec.add_development_dependency "nokogiri"
|
27
|
+
spec.add_development_dependency "pry"
|
24
28
|
spec.add_development_dependency "rake", "~> 10.0"
|
25
29
|
spec.add_development_dependency "rspec", "~> 3.0"
|
26
30
|
spec.add_development_dependency "rubocop"
|
31
|
+
spec.add_development_dependency "rubocop-rspec"
|
27
32
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.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-
|
11
|
+
date: 2018-07-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ruby-saml
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.8.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.8.0
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +66,34 @@ dependencies:
|
|
52
66
|
- - ">="
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: nokogiri
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
55
97
|
- !ruby/object:Gem::Dependency
|
56
98
|
name: rake
|
57
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,6 +136,20 @@ dependencies:
|
|
94
136
|
- - ">="
|
95
137
|
- !ruby/object:Gem::Version
|
96
138
|
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: rubocop-rspec
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
97
153
|
description:
|
98
154
|
email:
|
99
155
|
- davidlibrera@gmail.com
|
@@ -105,12 +161,15 @@ files:
|
|
105
161
|
- ".rspec"
|
106
162
|
- ".rubocop.yml"
|
107
163
|
- ".travis.yml"
|
164
|
+
- CHANGELOG.md
|
108
165
|
- CODE_OF_CONDUCT.md
|
109
166
|
- Gemfile
|
110
167
|
- LICENSE
|
111
168
|
- README.md
|
112
169
|
- Rakefile
|
113
170
|
- lib/spid.rb
|
171
|
+
- lib/spid/authn_request.rb
|
172
|
+
- lib/spid/onelogin_extension.rb
|
114
173
|
- lib/spid/version.rb
|
115
174
|
- spid.gemspec
|
116
175
|
homepage: https://github.com/italia/spid-ruby
|