saml2 1.1.0 → 1.1.1
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 +4 -4
- data/lib/saml2/authn_request.rb +63 -17
- data/lib/saml2/name_id.rb +33 -11
- data/lib/saml2/requested_authn_context.rb +16 -0
- data/lib/saml2/subject.rb +9 -9
- data/lib/saml2/version.rb +1 -1
- data/spec/lib/authn_request_spec.rb +18 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 788b9842bac7051e976ef2a7360d488f2a0249e1
|
4
|
+
data.tar.gz: 4c654aedef625b8c7ac918775158174406b570cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70b0409bc9a42a6c4786f5de2c3dfc09a18dc518e290fe450f3874695876c8f3ffb41e4baa59e0850c1af43a8f1aecc6a0978ec047f18c7d8b7d9407e5c6beb4
|
7
|
+
data.tar.gz: 802adedaadd6e2c033b4d6c7ec4e9d97fd7426bc8e7244ccd253cddbe89762466c03d59e0af98b7ca33f021abf42b8b1337ba537d703cd3e4e00bf4a2f78acf2
|
data/lib/saml2/authn_request.rb
CHANGED
@@ -7,6 +7,7 @@ require 'saml2/endpoint'
|
|
7
7
|
require 'saml2/name_id'
|
8
8
|
require 'saml2/namespaces'
|
9
9
|
require 'saml2/request'
|
10
|
+
require 'saml2/requested_authn_context'
|
10
11
|
require 'saml2/schemas'
|
11
12
|
require 'saml2/subject'
|
12
13
|
|
@@ -21,13 +22,14 @@ module SAML2
|
|
21
22
|
AuthnRequest.from_xml(Nokogiri::XML('<xml></xml>').root)
|
22
23
|
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
25
|
+
attr_writer :assertion_consumer_service_index,
|
26
|
+
:assertion_consumer_service_url,
|
27
|
+
:attribute_consuming_service_index,
|
28
|
+
:force_authn,
|
29
|
+
:name_id_policy,
|
30
|
+
:passive,
|
31
|
+
:protocol_binding
|
32
|
+
attr_accessor :requested_authn_context
|
31
33
|
|
32
34
|
def valid_web_browser_sso_profile?
|
33
35
|
return false unless issuer
|
@@ -64,37 +66,81 @@ module SAML2
|
|
64
66
|
end
|
65
67
|
|
66
68
|
def name_id_policy
|
67
|
-
|
69
|
+
if xml && !instance_variable_defined?(:@name_id_policy)
|
70
|
+
@name_id_policy = NameID::Policy.from_xml(xml.at_xpath('samlp:NameIDPolicy', Namespaces::ALL))
|
71
|
+
end
|
72
|
+
@name_id_policy
|
68
73
|
end
|
69
74
|
|
70
75
|
attr_reader :assertion_consumer_service, :attribute_consuming_service
|
71
76
|
|
72
|
-
def
|
73
|
-
xml
|
77
|
+
def assertion_consumer_service_index
|
78
|
+
if xml && !instance_variable_defined?(:@assertion_consumer_service_index)
|
79
|
+
@assertion_consumer_service_index = xml['AssertionConsumerServiceIndex']&.to_i
|
80
|
+
end
|
81
|
+
@assertion_consumer_service_index
|
74
82
|
end
|
75
83
|
|
76
|
-
def
|
77
|
-
xml
|
84
|
+
def assertion_consumer_service_url
|
85
|
+
if xml && !instance_variable_defined?(:@assertion_consumer_service_url)
|
86
|
+
@assertion_consumer_service_url = xml['AssertionConsumerServiceURL']
|
87
|
+
end
|
88
|
+
@assertion_consumer_service_url
|
78
89
|
end
|
79
90
|
|
80
91
|
def attribute_consuming_service_index
|
81
|
-
xml
|
92
|
+
if xml && !instance_variable_defined?(:@attribute_consuming_service_index)
|
93
|
+
@attribute_consuming_service_index = xml['AttributeConsumingServiceIndex']&.to_i
|
94
|
+
end
|
95
|
+
@attribute_consuming_service_index
|
82
96
|
end
|
83
97
|
|
84
98
|
def force_authn?
|
85
|
-
xml
|
99
|
+
if xml && !instance_variable_defined?(:@force_authn)
|
100
|
+
@force_authn = xml['ForceAuthn']&.== 'true'
|
101
|
+
end
|
102
|
+
@force_authn
|
86
103
|
end
|
87
104
|
|
88
105
|
def passive?
|
89
|
-
xml
|
106
|
+
if xml && !instance_variable_defined?(:@passive)
|
107
|
+
@passive = xml['IsPassive']&.== 'true'
|
108
|
+
end
|
109
|
+
@passive
|
90
110
|
end
|
91
111
|
|
92
112
|
def protocol_binding
|
93
|
-
xml
|
113
|
+
if xml && !instance_variable_defined?(:@protocol_binding)
|
114
|
+
@protocol_binding = xml['ProtocolBinding']
|
115
|
+
end
|
116
|
+
@protocol_binding
|
94
117
|
end
|
95
118
|
|
96
119
|
def subject
|
97
|
-
|
120
|
+
if xml && !instance_variable_defined?(:@subject)
|
121
|
+
@subject = Subject.from_xml(xml.at_xpath('saml:Subject', Namespaces::ALL))
|
122
|
+
end
|
123
|
+
@subject
|
124
|
+
end
|
125
|
+
|
126
|
+
def build(builder)
|
127
|
+
builder['samlp'].AuthnRequest(
|
128
|
+
'xmlns:samlp' => Namespaces::SAMLP,
|
129
|
+
'xmlns:saml' => Namespaces::SAML
|
130
|
+
) do |authn_request|
|
131
|
+
super(authn_request)
|
132
|
+
|
133
|
+
authn_request.parent['AssertionConsumerServiceIndex'] = assertion_consumer_service_index if assertion_consumer_service_index
|
134
|
+
authn_request.parent['AssertionConsumerServiceURL'] = assertion_consumer_service_url if assertion_consumer_service_url
|
135
|
+
authn_request.parent['AttributeConsumingServiceIndex'] = attribute_consuming_service_index if attribute_consuming_service_index
|
136
|
+
authn_request.parent['ForceAuthn'] = force_authn? unless force_authn?.nil?
|
137
|
+
authn_request.parent['IsPassive'] = passive? unless passive?.nil?
|
138
|
+
authn_request.parent['ProtocolBinding'] = protocol_binding if protocol_binding
|
139
|
+
|
140
|
+
subject.build(authn_request) if subject
|
141
|
+
name_id_policy.build(authn_request) if name_id_policy
|
142
|
+
requested_authn_context.build(authn_request) if requested_authn_context
|
143
|
+
end
|
98
144
|
end
|
99
145
|
end
|
100
146
|
end
|
data/lib/saml2/name_id.rb
CHANGED
@@ -13,26 +13,48 @@ module SAML2
|
|
13
13
|
X509_SUBJECT_NAME = "urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName".freeze
|
14
14
|
end
|
15
15
|
|
16
|
-
class Policy
|
17
|
-
|
16
|
+
class Policy < Base
|
17
|
+
attr_writer :allow_create, :format, :sp_name_qualifier
|
18
18
|
|
19
|
-
def
|
20
|
-
if
|
21
|
-
|
22
|
-
|
19
|
+
def initialize(allow_create = nil, format = nil, sp_name_qualifier = nil)
|
20
|
+
@allow_create = allow_create if allow_create
|
21
|
+
@format = format if format
|
22
|
+
@sp_name_qualifier = sp_name_qualifier if sp_name_qualifier
|
23
|
+
end
|
24
|
+
|
25
|
+
def allow_create?
|
26
|
+
if xml && !instance_variable_defined?(:@allow_create)
|
27
|
+
@allow_create = xml['AllowCreate']&.== 'true'
|
23
28
|
end
|
29
|
+
@allow_create
|
24
30
|
end
|
25
31
|
|
26
|
-
def
|
27
|
-
|
32
|
+
def format
|
33
|
+
if xml && !instance_variable_defined?(:@format)
|
34
|
+
@format = xml['Format']
|
35
|
+
end
|
36
|
+
@format
|
28
37
|
end
|
29
38
|
|
30
|
-
def
|
31
|
-
|
39
|
+
def sp_name_qualifier
|
40
|
+
if xml && !instance_variable_defined?(:@sp_name_qualifier)
|
41
|
+
@sp_name_qualifier = xml['SPNameQualifier']
|
42
|
+
end
|
43
|
+
@sp_name_qualifier
|
32
44
|
end
|
33
45
|
|
34
46
|
def ==(rhs)
|
35
|
-
|
47
|
+
allow_create? == rhs.allow_create? &&
|
48
|
+
format == rhs.format &&
|
49
|
+
sp_name_qualifier == rhs.sp_name_qualifier
|
50
|
+
end
|
51
|
+
|
52
|
+
def build(builder)
|
53
|
+
builder['samlp'].NameIDPolicy do |name_id_policy|
|
54
|
+
name_id_policy.parent['Format'] = format if format
|
55
|
+
name_id_policy.parent['SPNameQualifier'] = sp_name_qualifier if sp_name_qualifier
|
56
|
+
name_id_policy.parent['AllowCreate'] = allow_create? unless allow_create?.nil?
|
57
|
+
end
|
36
58
|
end
|
37
59
|
end
|
38
60
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'saml2/base'
|
2
|
+
|
3
|
+
module SAML2
|
4
|
+
class RequestedAuthnContext < Base
|
5
|
+
attr_accessor :comparison, :class_ref
|
6
|
+
|
7
|
+
def build(builder)
|
8
|
+
builder['samlp'].RequestedAuthnContext do |requested_authn_context|
|
9
|
+
requested_authn_context.parent['Comparison'] = comparison.to_s if comparison
|
10
|
+
Array(class_ref).each do |individual_class_ref|
|
11
|
+
requested_authn_context['saml'].AuthnContextClassRef(individual_class_ref)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/saml2/subject.rb
CHANGED
@@ -2,15 +2,15 @@ require 'saml2/name_id'
|
|
2
2
|
require 'saml2/namespaces'
|
3
3
|
|
4
4
|
module SAML2
|
5
|
-
class Subject
|
6
|
-
|
5
|
+
class Subject < Base
|
6
|
+
attr_writer :name_id
|
7
|
+
attr_accessor :confirmation
|
7
8
|
|
8
|
-
def
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
subject
|
9
|
+
def name_id
|
10
|
+
if xml && !instance_variable_defined?(:@name_id)
|
11
|
+
@name_id = NameID.from_xml(node.at_xpath('saml:NameID', Namespaces::ALL))
|
12
|
+
end
|
13
|
+
@name_id
|
14
14
|
end
|
15
15
|
|
16
16
|
def build(builder)
|
@@ -20,7 +20,7 @@ module SAML2
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
class Confirmation
|
23
|
+
class Confirmation < Base
|
24
24
|
module Methods
|
25
25
|
BEARER = 'urn:oasis:names:tc:SAML:2.0:cm:bearer'.freeze
|
26
26
|
HOLDER_OF_KEY = 'urn:oasis:names:tc:SAML:2.0:cm:holder-of-key'.freeze
|
data/lib/saml2/version.rb
CHANGED
@@ -42,7 +42,24 @@ module SAML2
|
|
42
42
|
end
|
43
43
|
|
44
44
|
it "should find the NameID policy" do
|
45
|
-
expect(request.name_id_policy).to eq NameID::Policy.new(true, NameID::Format::PERSISTENT)
|
45
|
+
expect(request.name_id_policy).to eq NameID::Policy.new(true, NameID::Format::PERSISTENT, "moodle.bridge.feide.no")
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'serializes valid XML' do
|
49
|
+
authn_request = AuthnRequest.new
|
50
|
+
authn_request.issuer = NameID.new("entity")
|
51
|
+
authn_request.protocol_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
52
|
+
authn_request.assertion_consumer_service_url = 'https://somewhere/'
|
53
|
+
authn_request.name_id_policy = NameID::Policy.new(true, NameID::Format::UNSPECIFIED)
|
54
|
+
authn_request.requested_authn_context = RequestedAuthnContext.new
|
55
|
+
authn_request.requested_authn_context.class_ref = "urn:oasis:names:tc:SAML:2.0:ac:classes:Password"
|
56
|
+
authn_request.requested_authn_context.comparison = :exact
|
57
|
+
authn_request.passive = true
|
58
|
+
xml = authn_request.to_s
|
59
|
+
authn_request = AuthnRequest.parse(xml)
|
60
|
+
expect(authn_request).to be_valid_schema
|
61
|
+
expect(authn_request.force_authn?).to eq nil
|
62
|
+
expect(authn_request.passive?).to eq true
|
46
63
|
end
|
47
64
|
end
|
48
65
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: saml2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cody Cutrer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-06-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -59,7 +59,7 @@ dependencies:
|
|
59
59
|
version: '3.2'
|
60
60
|
- - "<"
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
version: '5.
|
62
|
+
version: '5.2'
|
63
63
|
type: :runtime
|
64
64
|
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -69,7 +69,7 @@ dependencies:
|
|
69
69
|
version: '3.2'
|
70
70
|
- - "<"
|
71
71
|
- !ruby/object:Gem::Version
|
72
|
-
version: '5.
|
72
|
+
version: '5.2'
|
73
73
|
- !ruby/object:Gem::Dependency
|
74
74
|
name: byebug
|
75
75
|
requirement: !ruby/object:Gem::Requirement
|
@@ -154,6 +154,7 @@ files:
|
|
154
154
|
- lib/saml2/organization.rb
|
155
155
|
- lib/saml2/organization_and_contacts.rb
|
156
156
|
- lib/saml2/request.rb
|
157
|
+
- lib/saml2/requested_authn_context.rb
|
157
158
|
- lib/saml2/response.rb
|
158
159
|
- lib/saml2/role.rb
|
159
160
|
- lib/saml2/schemas.rb
|