saml2 1.0.5 → 1.0.6
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/attribute.rb +1 -4
- data/lib/saml2/attribute_consuming_service.rb +2 -2
- data/lib/saml2/base.rb +5 -4
- data/lib/saml2/endpoint.rb +1 -2
- data/lib/saml2/entity.rb +61 -14
- data/lib/saml2/identity_provider.rb +14 -8
- data/lib/saml2/indexed_object.rb +6 -1
- data/lib/saml2/key.rb +8 -0
- data/lib/saml2/organization_and_contacts.rb +9 -5
- data/lib/saml2/role.rb +10 -6
- data/lib/saml2/schemas.rb +4 -0
- data/lib/saml2/service_provider.rb +0 -8
- data/lib/saml2/sso.rb +9 -5
- data/lib/saml2/version.rb +1 -1
- data/schemas/MetadataExchange.xsd +112 -0
- data/schemas/oasis-200401-wss-wssecurity-secext-1.0.xsd +195 -0
- data/schemas/oasis-200401-wss-wssecurity-utility-1.0.xsd +108 -0
- data/schemas/ws-addr.xsd +137 -0
- data/schemas/ws-authorization.xsd +145 -0
- data/schemas/ws-federation.xsd +471 -0
- data/schemas/ws-securitypolicy-1.2.xsd +1205 -0
- data/spec/fixtures/FederationMetadata.xml +670 -0
- data/spec/fixtures/identity_provider.xml +45 -0
- data/spec/lib/entity_spec.rb +4 -0
- data/spec/lib/identity_provider_spec.rb +14 -0
- data/spec/lib/service_provider_spec.rb +1 -1
- metadata +18 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 102b176691a071893741f0bf750836e0bc72e8f0
|
4
|
+
data.tar.gz: afac3ee0941535c504f75c7b24137f55a1021f27
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a982caa3e5e5ac9ad4a392f8b6a680f85e330b0a3ed898a2b9dccf2896f4a282a1aba14e5743466aaac7f4b368ff8b40e75ccb03ef2e89b35c658c9a90b1a16
|
7
|
+
data.tar.gz: 251540ba69cc06316961865d9333b5d4da0a8ebcb3c9622039483c87ce222f9e221280087bcfedc36669c77f6539a27716f228fb0218083c6a590c0b7ed51b75
|
data/lib/saml2/attribute.rb
CHANGED
@@ -24,7 +24,7 @@ module SAML2
|
|
24
24
|
|
25
25
|
def from_xml(node)
|
26
26
|
# pass through for subclasses
|
27
|
-
super unless self == Attribute
|
27
|
+
return super unless self == Attribute
|
28
28
|
|
29
29
|
# look for an appropriate subclass
|
30
30
|
klass = class_for(node)
|
@@ -76,7 +76,6 @@ module SAML2
|
|
76
76
|
when 1; values.first
|
77
77
|
else; values
|
78
78
|
end
|
79
|
-
super
|
80
79
|
end
|
81
80
|
|
82
81
|
private
|
@@ -128,8 +127,6 @@ module SAML2
|
|
128
127
|
@attributes = node.xpath('saml:Attribute', Namespaces::ALL).map do |attr|
|
129
128
|
Attribute.from_xml(attr)
|
130
129
|
end
|
131
|
-
|
132
|
-
super
|
133
130
|
end
|
134
131
|
|
135
132
|
def build(builder)
|
@@ -12,8 +12,8 @@ module SAML2
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def from_xml(node)
|
15
|
-
@is_required = node['isRequired'] && node['isRequired'] == 'true'
|
16
15
|
super
|
16
|
+
@is_required = node['isRequired'] && node['isRequired'] == 'true'
|
17
17
|
end
|
18
18
|
|
19
19
|
def required?
|
@@ -47,13 +47,13 @@ module SAML2
|
|
47
47
|
attr_reader :name, :requested_attributes
|
48
48
|
|
49
49
|
def initialize(name = nil, requested_attributes = [])
|
50
|
+
super()
|
50
51
|
@name, @requested_attributes = name, requested_attributes
|
51
52
|
end
|
52
53
|
|
53
54
|
def from_xml(node)
|
54
55
|
@name = node['ServiceName']
|
55
56
|
@requested_attributes = load_object_array(node, "md:RequestedAttribute", RequestedAttribute)
|
56
|
-
super
|
57
57
|
end
|
58
58
|
|
59
59
|
def create_statement(attributes)
|
data/lib/saml2/base.rb
CHANGED
@@ -4,11 +4,12 @@ module SAML2
|
|
4
4
|
class Base
|
5
5
|
def self.from_xml(node)
|
6
6
|
return nil unless node
|
7
|
-
new
|
7
|
+
result = new
|
8
|
+
result.from_xml(node)
|
9
|
+
result
|
8
10
|
end
|
9
11
|
|
10
|
-
def from_xml(
|
11
|
-
self
|
12
|
+
def from_xml(_node)
|
12
13
|
end
|
13
14
|
|
14
15
|
def to_s
|
@@ -17,7 +18,7 @@ module SAML2
|
|
17
18
|
end
|
18
19
|
|
19
20
|
def to_xml
|
20
|
-
unless
|
21
|
+
unless instance_variable_defined?(:@document)
|
21
22
|
builder = Nokogiri::XML::Builder.new
|
22
23
|
build(builder)
|
23
24
|
@document = builder.doc
|
data/lib/saml2/endpoint.rb
CHANGED
@@ -11,7 +11,7 @@ module SAML2
|
|
11
11
|
|
12
12
|
attr_reader :location, :binding
|
13
13
|
|
14
|
-
def initialize(location, binding = Bindings::HTTP_POST)
|
14
|
+
def initialize(location = nil, binding = Bindings::HTTP_POST)
|
15
15
|
@location, @binding = location, binding
|
16
16
|
end
|
17
17
|
|
@@ -22,7 +22,6 @@ module SAML2
|
|
22
22
|
def from_xml(node)
|
23
23
|
@location = node['Location']
|
24
24
|
@binding = node['Binding']
|
25
|
-
self
|
26
25
|
end
|
27
26
|
|
28
27
|
def build(builder, element)
|
data/lib/saml2/entity.rb
CHANGED
@@ -28,44 +28,91 @@ module SAML2
|
|
28
28
|
|
29
29
|
class Group < Array
|
30
30
|
def self.from_xml(node)
|
31
|
-
node && new(node)
|
31
|
+
node && new.from_xml(node)
|
32
32
|
end
|
33
33
|
|
34
|
-
def initialize
|
35
|
-
@
|
34
|
+
def initialize
|
35
|
+
@valid_until = nil
|
36
|
+
end
|
37
|
+
|
38
|
+
def from_xml(node)
|
39
|
+
@root = node
|
40
|
+
remove_instance_variable(:@valid_until)
|
36
41
|
replace(Base.load_object_array(@root, "md:EntityDescriptor|md:EntitiesDescriptor",
|
37
42
|
'EntityDescriptor' => Entity,
|
38
43
|
'EntitiesDescriptor' => Group))
|
39
44
|
end
|
40
45
|
|
41
46
|
def valid_schema?
|
42
|
-
Schemas.
|
47
|
+
Schemas.federation.valid?(@root.document)
|
48
|
+
end
|
49
|
+
|
50
|
+
def signature
|
51
|
+
unless instance_variable_defined?(:@signature)
|
52
|
+
@signature = @root.at_xpath('dsig:Signature', Namespaces::ALL)
|
53
|
+
signed_node = @signature.at_xpath('dsig:SignedInfo/dsig:Reference', Namespaces::ALL)['URI']
|
54
|
+
@root.set_id_attribute('ID')
|
55
|
+
@signature = nil unless signed_node == "##{@root['ID']}"
|
56
|
+
end
|
57
|
+
@signature
|
58
|
+
end
|
59
|
+
|
60
|
+
def signed?
|
61
|
+
!!signature
|
62
|
+
end
|
63
|
+
|
64
|
+
def valid_signature?(*args)
|
65
|
+
signature.verify_with(*args)
|
66
|
+
end
|
67
|
+
|
68
|
+
def valid_until
|
69
|
+
unless instance_variable_defined?(:@valid_until)
|
70
|
+
@valid_until = @root['validUntil'] && Time.parse(@root['validUntil'])
|
71
|
+
end
|
72
|
+
@valid_until
|
43
73
|
end
|
44
74
|
end
|
45
75
|
|
46
|
-
def
|
47
|
-
|
76
|
+
def initialize
|
77
|
+
super
|
78
|
+
@valid_until = nil
|
79
|
+
@entity_id = nil
|
80
|
+
@roles = []
|
48
81
|
end
|
49
82
|
|
50
|
-
def
|
83
|
+
def from_xml(node)
|
84
|
+
@root = node
|
85
|
+
remove_instance_variable(:@valid_until)
|
86
|
+
@roles = nil
|
51
87
|
super
|
52
|
-
@root = root
|
53
|
-
unless @root
|
54
|
-
@roles = []
|
55
|
-
end
|
56
88
|
end
|
57
89
|
|
58
90
|
def valid_schema?
|
59
|
-
Schemas.
|
91
|
+
Schemas.federation.valid?(@root.document)
|
60
92
|
end
|
61
93
|
|
62
94
|
def entity_id
|
63
95
|
@entity_id || @root && @root['entityID']
|
64
96
|
end
|
65
97
|
|
98
|
+
def valid_until
|
99
|
+
unless instance_variable_defined?(:@valid_until)
|
100
|
+
@valid_until = @root['validUntil'] && Time.parse(@root['validUntil'])
|
101
|
+
end
|
102
|
+
@valid_until
|
103
|
+
end
|
104
|
+
|
105
|
+
def identity_providers
|
106
|
+
roles.select { |r| r.is_a?(IdentityProvider) }
|
107
|
+
end
|
108
|
+
|
109
|
+
def service_providers
|
110
|
+
roles.select { |r| r.is_a?(ServiceProvider) }
|
111
|
+
end
|
112
|
+
|
66
113
|
def roles
|
67
|
-
|
68
|
-
|
114
|
+
@roles ||= load_object_array(@root, 'md:IDPSSODescriptor', IdentityProvider) +
|
115
|
+
load_object_array(@root, 'md:SPSSODescriptor', ServiceProvider)
|
69
116
|
end
|
70
117
|
|
71
118
|
def build(builder)
|
@@ -5,14 +5,20 @@ module SAML2
|
|
5
5
|
class IdentityProvider < SSO
|
6
6
|
attr_writer :want_authn_requests_signed, :single_sign_on_services, :attribute_profiles, :attributes
|
7
7
|
|
8
|
-
def initialize
|
9
|
-
super
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
8
|
+
def initialize
|
9
|
+
super
|
10
|
+
@want_authn_requests_signed = nil
|
11
|
+
@single_sign_on_services = []
|
12
|
+
@attribute_profiles = []
|
13
|
+
@attributes = []
|
14
|
+
end
|
15
|
+
|
16
|
+
def from_xml(node)
|
17
|
+
super
|
18
|
+
remove_instance_variable(:@want_authn_requests_signed)
|
19
|
+
@single_sign_on_services = nil
|
20
|
+
@attribute_profiles = nil
|
21
|
+
@attributes = nil
|
16
22
|
end
|
17
23
|
|
18
24
|
def want_authn_requests_signed?
|
data/lib/saml2/indexed_object.rb
CHANGED
@@ -4,6 +4,11 @@ module SAML2
|
|
4
4
|
module IndexedObject
|
5
5
|
attr_reader :index
|
6
6
|
|
7
|
+
def initialize(*args)
|
8
|
+
@is_default = nil
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
7
12
|
def eql?(rhs)
|
8
13
|
index == rhs.index &&
|
9
14
|
default? == rhs.default? &&
|
@@ -11,7 +16,7 @@ module SAML2
|
|
11
16
|
end
|
12
17
|
|
13
18
|
def default?
|
14
|
-
|
19
|
+
!!@is_default
|
15
20
|
end
|
16
21
|
|
17
22
|
def from_xml(node)
|
data/lib/saml2/key.rb
CHANGED
@@ -29,6 +29,14 @@ module SAML2
|
|
29
29
|
use.nil? || use == Type::SIGNING
|
30
30
|
end
|
31
31
|
|
32
|
+
def certificate
|
33
|
+
@certificate ||= OpenSSL::X509::Certificate.new(Base64.decode64(x509))
|
34
|
+
end
|
35
|
+
|
36
|
+
def fingerprint
|
37
|
+
@fingerprint ||= Digest::SHA1.hexdigest(certificate.to_der).gsub(/(\h{2})(?=\h)/, '\1:')
|
38
|
+
end
|
39
|
+
|
32
40
|
def build(builder)
|
33
41
|
builder['md'].KeyDescriptor do |builder|
|
34
42
|
builder.parent['use'] = use if use
|
@@ -5,11 +5,15 @@ module SAML2
|
|
5
5
|
module OrganizationAndContacts
|
6
6
|
attr_writer :organization, :contacts
|
7
7
|
|
8
|
-
def initialize
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
def initialize
|
9
|
+
@organization = nil
|
10
|
+
@contacts = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def from_xml(node)
|
14
|
+
remove_instance_variable(:@organization)
|
15
|
+
@contacts = nil
|
16
|
+
super
|
13
17
|
end
|
14
18
|
|
15
19
|
def organization
|
data/lib/saml2/role.rb
CHANGED
@@ -14,14 +14,18 @@ module SAML2
|
|
14
14
|
|
15
15
|
attr_writer :supported_protocols, :keys
|
16
16
|
|
17
|
-
def initialize
|
17
|
+
def initialize
|
18
|
+
super
|
19
|
+
@supported_protocols = Set.new
|
20
|
+
@supported_protocols << Protocols::SAML2
|
21
|
+
@keys = []
|
22
|
+
end
|
23
|
+
|
24
|
+
def from_xml(node)
|
18
25
|
super
|
19
26
|
@root = node
|
20
|
-
|
21
|
-
|
22
|
-
@supported_protocols << Protocols::SAML2
|
23
|
-
@keys = []
|
24
|
-
end
|
27
|
+
@supported_protocols = nil
|
28
|
+
@keys = nil
|
25
29
|
end
|
26
30
|
|
27
31
|
def supported_protocols
|
data/lib/saml2/schemas.rb
CHANGED
@@ -5,14 +5,6 @@ require 'saml2/sso'
|
|
5
5
|
|
6
6
|
module SAML2
|
7
7
|
class ServiceProvider < SSO
|
8
|
-
class << self
|
9
|
-
alias_method :from_xml, :new
|
10
|
-
end
|
11
|
-
|
12
|
-
def initialize(root)
|
13
|
-
@root = root
|
14
|
-
end
|
15
|
-
|
16
8
|
def assertion_consumer_services
|
17
9
|
@assertion_consumer_services ||= begin
|
18
10
|
nodes = @root.xpath('md:AssertionConsumerService', Namespaces::ALL)
|
data/lib/saml2/sso.rb
CHANGED
@@ -4,12 +4,16 @@ module SAML2
|
|
4
4
|
class SSO < Role
|
5
5
|
attr_reader :single_logout_services, :name_id_formats
|
6
6
|
|
7
|
-
def initialize
|
7
|
+
def initialize
|
8
8
|
super
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
@single_logout_services = []
|
10
|
+
@name_id_formats = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def from_xml(node)
|
14
|
+
super
|
15
|
+
@single_logout_services = nil
|
16
|
+
@name_id_formats = nil
|
13
17
|
end
|
14
18
|
|
15
19
|
def single_logout_services
|
data/lib/saml2/version.rb
CHANGED
@@ -0,0 +1,112 @@
|
|
1
|
+
<?xml version='1.0' encoding='UTF-8' ?>
|
2
|
+
<!--
|
3
|
+
(c) 2004-2006 BEA Systems Inc., Computer Associates International, Inc.,
|
4
|
+
International Business Machines Corporation, Microsoft Corporation,
|
5
|
+
Inc., SAP AG, Sun Microsystems, and webMethods. All rights reserved.
|
6
|
+
|
7
|
+
Permission to copy and display the WS-MetadataExchange Specification
|
8
|
+
(the "Specification"), in any medium without fee or royalty is hereby
|
9
|
+
granted, provided that you include the following on ALL copies of the
|
10
|
+
Specification that you make:
|
11
|
+
|
12
|
+
1. A link or URL to the Specification at this location.
|
13
|
+
2. The copyright notice as shown in the Specification.
|
14
|
+
|
15
|
+
BEA Systems, Computer Associates, IBM, Microsoft, SAP, Sun, and
|
16
|
+
webMethods (collectively, the "Authors") each agree to grant you a
|
17
|
+
license, under royalty-free and otherwise reasonable,
|
18
|
+
non-discriminatory terms and conditions, to their respective essential
|
19
|
+
patent claims that they deem necessary to implement the
|
20
|
+
WS-MetadataExchange Specification.
|
21
|
+
|
22
|
+
THE SPECIFICATION IS PROVIDED "AS IS," AND THE AUTHORS MAKE NO
|
23
|
+
REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT
|
24
|
+
LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
25
|
+
PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF THE
|
26
|
+
SPECIFICATION ARE SUITABLE FOR ANY PURPOSE; NOR THAT THE
|
27
|
+
IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY
|
28
|
+
PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
|
29
|
+
|
30
|
+
THE AUTHORS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL,
|
31
|
+
INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING TO ANY
|
32
|
+
USE OR DISTRIBUTION OF THE SPECIFICATIONS.
|
33
|
+
|
34
|
+
The name and trademarks of the Authors may NOT be used in any manner,
|
35
|
+
including advertising or publicity pertaining to the Specifications or
|
36
|
+
their contents without specific, written prior permission. Title to
|
37
|
+
copyright in the Specifications will at all times remain with the
|
38
|
+
Authors.
|
39
|
+
|
40
|
+
No other rights are granted by implication, estoppel or otherwise.
|
41
|
+
-->
|
42
|
+
|
43
|
+
<xs:schema
|
44
|
+
targetNamespace='http://schemas.xmlsoap.org/ws/2004/09/mex'
|
45
|
+
xmlns:tns='http://schemas.xmlsoap.org/ws/2004/09/mex'
|
46
|
+
xmlns:wsa10='http://www.w3.org/2005/08/addressing'
|
47
|
+
xmlns:wsa04='http://schemas.xmlsoap.org/ws/2004/08/addressing'
|
48
|
+
xmlns:xs='http://www.w3.org/2001/XMLSchema'
|
49
|
+
elementFormDefault='qualified'
|
50
|
+
blockDefault='#all' >
|
51
|
+
|
52
|
+
<!-- Get Metadata request -->
|
53
|
+
<xs:element name='GetMetadata' >
|
54
|
+
<xs:complexType>
|
55
|
+
<xs:sequence>
|
56
|
+
<xs:element ref='tns:Dialect' minOccurs='0' />
|
57
|
+
<xs:element ref='tns:Identifier' minOccurs='0' />
|
58
|
+
</xs:sequence>
|
59
|
+
<xs:anyAttribute namespace='##other' processContents='lax' />
|
60
|
+
</xs:complexType>
|
61
|
+
</xs:element>
|
62
|
+
|
63
|
+
<xs:element name='Dialect' type='xs:anyURI' />
|
64
|
+
<xs:element name='Identifier' type='xs:anyURI' />
|
65
|
+
|
66
|
+
<!-- Get Metadata response -->
|
67
|
+
<xs:element name='Metadata' >
|
68
|
+
<xs:complexType>
|
69
|
+
<xs:sequence>
|
70
|
+
<xs:element ref='tns:MetadataSection'
|
71
|
+
minOccurs='0'
|
72
|
+
maxOccurs='unbounded' />
|
73
|
+
<xs:any namespace='##other' processContents='lax'
|
74
|
+
minOccurs='0'
|
75
|
+
maxOccurs='unbounded' />
|
76
|
+
</xs:sequence>
|
77
|
+
<xs:anyAttribute namespace='##other' processContents='lax' />
|
78
|
+
</xs:complexType>
|
79
|
+
</xs:element>
|
80
|
+
|
81
|
+
<xs:element name='MetadataSection' >
|
82
|
+
<xs:complexType>
|
83
|
+
<xs:choice>
|
84
|
+
<xs:any namespace='##other' processContents='lax' />
|
85
|
+
<xs:element ref='tns:MetadataReference' />
|
86
|
+
<xs:element ref='tns:Location' />
|
87
|
+
</xs:choice>
|
88
|
+
<xs:attribute name='Dialect' type='xs:anyURI' use='required' />
|
89
|
+
<xs:attribute name='Identifier' type='xs:anyURI' />
|
90
|
+
<xs:anyAttribute namespace='##other' processContents='lax' />
|
91
|
+
</xs:complexType>
|
92
|
+
</xs:element>
|
93
|
+
|
94
|
+
<!--
|
95
|
+
Ideally, the type of the MetadataReference would have been
|
96
|
+
the union of wsa04:EndpointReferenceType and
|
97
|
+
wsa10:EndpointReferenceType but unfortunately xs:union only
|
98
|
+
works for simple types. As a result, we have to define
|
99
|
+
the mex:MetadataReference using xs:any.
|
100
|
+
-->
|
101
|
+
|
102
|
+
<xs:element name='MetadataReference'>
|
103
|
+
<xs:complexType>
|
104
|
+
<xs:sequence>
|
105
|
+
<xs:any minOccurs='1' maxOccurs='unbounded'
|
106
|
+
processContents='lax' namespace='##other' />
|
107
|
+
</xs:sequence>
|
108
|
+
</xs:complexType>
|
109
|
+
</xs:element>
|
110
|
+
<xs:element name='Location'
|
111
|
+
type='xs:anyURI' />
|
112
|
+
</xs:schema>
|