saml2 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Rakefile +13 -0
- data/app/views/saml2/http_post.html.erb +14 -0
- data/lib/saml2.rb +9 -0
- data/lib/saml2/assertion.rb +37 -0
- data/lib/saml2/attribute.rb +127 -0
- data/lib/saml2/attribute/x500.rb +79 -0
- data/lib/saml2/attribute_consuming_service.rb +76 -0
- data/lib/saml2/authn_request.rb +116 -0
- data/lib/saml2/authn_statement.rb +26 -0
- data/lib/saml2/base.rb +53 -0
- data/lib/saml2/contact.rb +50 -0
- data/lib/saml2/endpoint.rb +46 -0
- data/lib/saml2/engine.rb +4 -0
- data/lib/saml2/entity.rb +84 -0
- data/lib/saml2/identity_provider.rb +57 -0
- data/lib/saml2/indexed_object.rb +59 -0
- data/lib/saml2/key.rb +46 -0
- data/lib/saml2/name_id.rb +60 -0
- data/lib/saml2/namespaces.rb +21 -0
- data/lib/saml2/organization.rb +74 -0
- data/lib/saml2/organization_and_contacts.rb +35 -0
- data/lib/saml2/profiles.rb +7 -0
- data/lib/saml2/response.rb +92 -0
- data/lib/saml2/role.rb +53 -0
- data/lib/saml2/schemas.rb +18 -0
- data/lib/saml2/service_provider.rb +30 -0
- data/lib/saml2/sso.rb +36 -0
- data/lib/saml2/subject.rb +49 -0
- data/lib/saml2/version.rb +3 -0
- data/schemas/saml-schema-assertion-2.0.xsd +283 -0
- data/schemas/saml-schema-metadata-2.0.xsd +339 -0
- data/schemas/saml-schema-protocol-2.0.xsd +302 -0
- data/schemas/xenc-schema.xsd +136 -0
- data/schemas/xml.xsd +287 -0
- data/schemas/xmldsig-core-schema.xsd +309 -0
- data/spec/fixtures/authnrequest.xml +12 -0
- data/spec/fixtures/calculated.txt +1 -0
- data/spec/fixtures/certificate.pem +25 -0
- data/spec/fixtures/entities.xml +13 -0
- data/spec/fixtures/privatekey.key +27 -0
- data/spec/fixtures/response_signed.xml +47 -0
- data/spec/fixtures/response_with_attribute_signed.xml +47 -0
- data/spec/fixtures/service_provider.xml +79 -0
- data/spec/fixtures/xmlsec.txt +1 -0
- data/spec/lib/attribute_consuming_service_spec.rb +74 -0
- data/spec/lib/attribute_spec.rb +39 -0
- data/spec/lib/authn_request_spec.rb +52 -0
- data/spec/lib/entity_spec.rb +45 -0
- data/spec/lib/identity_provider_spec.rb +23 -0
- data/spec/lib/indexed_object_spec.rb +38 -0
- data/spec/lib/response_spec.rb +60 -0
- data/spec/lib/service_provider_spec.rb +30 -0
- data/spec/spec_helper.rb +6 -0
- metadata +191 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
module SAML2
|
4
|
+
describe IdentityProvider do
|
5
|
+
it "should serialize valid xml" do
|
6
|
+
entity = Entity.new
|
7
|
+
entity.entity_id = 'http://sso.canvaslms.com/SAML2'
|
8
|
+
entity.organization = Organization.new('Canvas', 'Canvas by Instructure', 'https://www.canvaslms.com/')
|
9
|
+
contact = Contact.new(Contact::Type::TECHNICAL)
|
10
|
+
contact.company = 'Instructure'
|
11
|
+
contact.email_addresses << 'mailto:ops@instructure.com'
|
12
|
+
entity.contacts << contact
|
13
|
+
|
14
|
+
idp = IdentityProvider.new
|
15
|
+
idp.name_id_formats << NameID::Format::PERSISTENT
|
16
|
+
idp.single_sign_on_services << Endpoint.new('https://sso.canvaslms.com/SAML2/Login')
|
17
|
+
idp.keys << Key.new('somedata', Key::Type::SIGNING)
|
18
|
+
|
19
|
+
entity.roles << idp
|
20
|
+
Schemas.metadata.validate(Nokogiri::XML(entity.to_s)).must_equal []
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
module SAML2
|
4
|
+
describe IndexedObject::Array do
|
5
|
+
it "should sort by index" do
|
6
|
+
acses = Endpoint::Indexed::Array.new(
|
7
|
+
[Endpoint::Indexed.new('b', 1),
|
8
|
+
Endpoint::Indexed.new('a', 0)])
|
9
|
+
acses.map(&:location).must_equal ['a', 'b']
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should be accessible by index" do
|
13
|
+
acses = Endpoint::Indexed::Array.new(
|
14
|
+
[Endpoint::Indexed.new('b', 3),
|
15
|
+
Endpoint::Indexed.new('a', 1)])
|
16
|
+
acses.map(&:location).must_equal ['a', 'b']
|
17
|
+
acses[1].location.must_equal 'a'
|
18
|
+
acses[3].location.must_equal 'b'
|
19
|
+
acses[0].must_equal nil
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#default" do
|
23
|
+
it "should default to first entry if not otherwise specified" do
|
24
|
+
acses = Endpoint::Indexed::Array.new(
|
25
|
+
[Endpoint::Indexed.new('a', 0),
|
26
|
+
Endpoint::Indexed.new('b', 1)])
|
27
|
+
acses.default.location.must_equal 'a'
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should default to a tagged default" do
|
31
|
+
acses = Endpoint::Indexed::Array.new(
|
32
|
+
[Endpoint::Indexed.new('a', 0),
|
33
|
+
Endpoint::Indexed.new('b', 1, true)])
|
34
|
+
acses.default.location.must_equal 'b'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
module SAML2
|
4
|
+
describe Response do
|
5
|
+
let(:sp) { Entity.parse(fixture('service_provider.xml')).roles.first }
|
6
|
+
|
7
|
+
let(:request) do
|
8
|
+
request = AuthnRequest.parse(fixture('authnrequest.xml'))
|
9
|
+
request.resolve(sp)
|
10
|
+
request
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:response) do
|
14
|
+
response = Response.respond_to(request,
|
15
|
+
NameID.new('issuer'),
|
16
|
+
NameID.new('jacob', NameID::Format::PERSISTENT))
|
17
|
+
response
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should generate valid XML" do
|
21
|
+
xml = response.to_s
|
22
|
+
Schemas.protocol.validate(Nokogiri::XML(xml)).must_equal []
|
23
|
+
end
|
24
|
+
|
25
|
+
def freeze_response
|
26
|
+
response.instance_variable_set(:@id, "_9a15e699-2d04-4ba7-a521-cfa4dcd21f44")
|
27
|
+
assertion = response.assertions.first
|
28
|
+
assertion.instance_variable_set(:@id, "_cdfc3faf-90ad-462f-880d-677483210684")
|
29
|
+
response.instance_variable_set(:@issue_instant, Time.parse("2015-02-12T22:51:29Z"))
|
30
|
+
assertion.instance_variable_set(:@issue_instant, Time.parse("2015-02-12T22:51:29Z"))
|
31
|
+
assertion.statements.first.authn_instant = Time.parse("2015-02-12T22:51:29Z")
|
32
|
+
confirmation = assertion.subject.confirmation
|
33
|
+
confirmation.not_before = Time.parse("2015-02-12T22:51:29Z")
|
34
|
+
confirmation.not_on_or_after = Time.parse("2015-02-12T22:54:29Z")
|
35
|
+
confirmation.recipient = response.destination
|
36
|
+
confirmation.in_response_to = response.in_response_to
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should generate a valid signature" do
|
40
|
+
freeze_response
|
41
|
+
response.sign(fixture('certificate.pem'), fixture('privatekey.key'))
|
42
|
+
# verifiable on the command line with:
|
43
|
+
# xmlsec1 --verify --pubkey-cert-pem certificate.pem --privkey-pem privatekey.key --id-attr:ID urn:oasis:names:tc:SAML:2.0:assertion:Assertion response_signed.xml
|
44
|
+
response.to_s.must_equal fixture('response_signed.xml')
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should generate a valid signature when attributes are present" do
|
48
|
+
freeze_response
|
49
|
+
response.assertions.first.statements << sp.attribute_consuming_services.default.create_statement('givenName' => 'cody')
|
50
|
+
response.sign(fixture('certificate.pem'), fixture('privatekey.key'))
|
51
|
+
response.to_s.must_equal fixture('response_with_attribute_signed.xml')
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should generate valid XML for IdP initiated response" do
|
55
|
+
response = Response.initiate(sp, NameID.new('issuer'),
|
56
|
+
NameID.new('jacob', NameID::Format::PERSISTENT))
|
57
|
+
Schemas.protocol.validate(Nokogiri::XML(response.to_s)).must_equal []
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
module SAML2
|
4
|
+
describe ServiceProvider do
|
5
|
+
describe "valid metadata" do
|
6
|
+
let(:entity) { Entity.parse(fixture('service_provider.xml')) }
|
7
|
+
let(:sp) { entity.roles.first }
|
8
|
+
|
9
|
+
it "should create the assertion_consumer_services array" do
|
10
|
+
sp.assertion_consumer_services.length.must_equal 4
|
11
|
+
sp.assertion_consumer_services.map(&:index).must_equal [0, 1, 2, 3]
|
12
|
+
sp.assertion_consumer_services.first.location.must_equal 'https://siteadmin.instructure.com/saml_consume'
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should find the signing certificate" do
|
16
|
+
sp.signing_keys.first.x509.must_match /MIIE8TCCA9mgAwIBAgIJAITusxON60cKMA0GCSqGSIb3DQEBBQUAMIGrMQswCQYD/
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should load the organization" do
|
20
|
+
entity.organization.display_name.must_equal 'Canvas'
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should load contacts" do
|
24
|
+
entity.contacts.length.must_equal 1
|
25
|
+
entity.contacts.first.type.must_equal Contact::Type::TECHNICAL
|
26
|
+
entity.contacts.first.surname.must_equal 'Administrator'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,191 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: saml2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Cody Cutrer
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-03-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: nokogiri
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.5.8
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '1.7'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.5.8
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '1.7'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: nokogiri-xmlsec-me-harder
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0.9'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 0.9.2
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0.9'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 0.9.2
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: rake
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0'
|
60
|
+
type: :development
|
61
|
+
prerelease: false
|
62
|
+
version_requirements: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: minitest
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
type: :development
|
75
|
+
prerelease: false
|
76
|
+
version_requirements: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
81
|
+
description: |2
|
82
|
+
The saml2 library is yet another SAML library for Ruby, with
|
83
|
+
an emphasis on _not_ re-implementing XML, especially XML Security,
|
84
|
+
_not_ parsing via Regex or generating XML by string concatenation,
|
85
|
+
_not_ serializing/re-parsing multiple times just to get it into
|
86
|
+
the correct format to sign or validate.
|
87
|
+
|
88
|
+
For now, it provides a clean interface for implementing an IdP,
|
89
|
+
but not an SP.
|
90
|
+
email: cody@instructure.com'
|
91
|
+
executables: []
|
92
|
+
extensions: []
|
93
|
+
extra_rdoc_files: []
|
94
|
+
files:
|
95
|
+
- Rakefile
|
96
|
+
- app/views/saml2/http_post.html.erb
|
97
|
+
- lib/saml2.rb
|
98
|
+
- lib/saml2/assertion.rb
|
99
|
+
- lib/saml2/attribute.rb
|
100
|
+
- lib/saml2/attribute/x500.rb
|
101
|
+
- lib/saml2/attribute_consuming_service.rb
|
102
|
+
- lib/saml2/authn_request.rb
|
103
|
+
- lib/saml2/authn_statement.rb
|
104
|
+
- lib/saml2/base.rb
|
105
|
+
- lib/saml2/contact.rb
|
106
|
+
- lib/saml2/endpoint.rb
|
107
|
+
- lib/saml2/engine.rb
|
108
|
+
- lib/saml2/entity.rb
|
109
|
+
- lib/saml2/identity_provider.rb
|
110
|
+
- lib/saml2/indexed_object.rb
|
111
|
+
- lib/saml2/key.rb
|
112
|
+
- lib/saml2/name_id.rb
|
113
|
+
- lib/saml2/namespaces.rb
|
114
|
+
- lib/saml2/organization.rb
|
115
|
+
- lib/saml2/organization_and_contacts.rb
|
116
|
+
- lib/saml2/profiles.rb
|
117
|
+
- lib/saml2/response.rb
|
118
|
+
- lib/saml2/role.rb
|
119
|
+
- lib/saml2/schemas.rb
|
120
|
+
- lib/saml2/service_provider.rb
|
121
|
+
- lib/saml2/sso.rb
|
122
|
+
- lib/saml2/subject.rb
|
123
|
+
- lib/saml2/version.rb
|
124
|
+
- schemas/saml-schema-assertion-2.0.xsd
|
125
|
+
- schemas/saml-schema-metadata-2.0.xsd
|
126
|
+
- schemas/saml-schema-protocol-2.0.xsd
|
127
|
+
- schemas/xenc-schema.xsd
|
128
|
+
- schemas/xml.xsd
|
129
|
+
- schemas/xmldsig-core-schema.xsd
|
130
|
+
- spec/fixtures/authnrequest.xml
|
131
|
+
- spec/fixtures/calculated.txt
|
132
|
+
- spec/fixtures/certificate.pem
|
133
|
+
- spec/fixtures/entities.xml
|
134
|
+
- spec/fixtures/privatekey.key
|
135
|
+
- spec/fixtures/response_signed.xml
|
136
|
+
- spec/fixtures/response_with_attribute_signed.xml
|
137
|
+
- spec/fixtures/service_provider.xml
|
138
|
+
- spec/fixtures/xmlsec.txt
|
139
|
+
- spec/lib/attribute_consuming_service_spec.rb
|
140
|
+
- spec/lib/attribute_spec.rb
|
141
|
+
- spec/lib/authn_request_spec.rb
|
142
|
+
- spec/lib/entity_spec.rb
|
143
|
+
- spec/lib/identity_provider_spec.rb
|
144
|
+
- spec/lib/indexed_object_spec.rb
|
145
|
+
- spec/lib/response_spec.rb
|
146
|
+
- spec/lib/service_provider_spec.rb
|
147
|
+
- spec/spec_helper.rb
|
148
|
+
homepage: https://github.com/instructure/ruby-saml2
|
149
|
+
licenses:
|
150
|
+
- MIT
|
151
|
+
metadata: {}
|
152
|
+
post_install_message:
|
153
|
+
rdoc_options: []
|
154
|
+
require_paths:
|
155
|
+
- lib
|
156
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - ">="
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: '0'
|
161
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
162
|
+
requirements:
|
163
|
+
- - ">="
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
requirements: []
|
167
|
+
rubyforge_project:
|
168
|
+
rubygems_version: 2.4.5
|
169
|
+
signing_key:
|
170
|
+
specification_version: 4
|
171
|
+
summary: SAML 2.0 Library
|
172
|
+
test_files:
|
173
|
+
- spec/fixtures/authnrequest.xml
|
174
|
+
- spec/fixtures/calculated.txt
|
175
|
+
- spec/fixtures/certificate.pem
|
176
|
+
- spec/fixtures/entities.xml
|
177
|
+
- spec/fixtures/privatekey.key
|
178
|
+
- spec/fixtures/response_signed.xml
|
179
|
+
- spec/fixtures/response_with_attribute_signed.xml
|
180
|
+
- spec/fixtures/service_provider.xml
|
181
|
+
- spec/fixtures/xmlsec.txt
|
182
|
+
- spec/lib/attribute_consuming_service_spec.rb
|
183
|
+
- spec/lib/attribute_spec.rb
|
184
|
+
- spec/lib/authn_request_spec.rb
|
185
|
+
- spec/lib/entity_spec.rb
|
186
|
+
- spec/lib/identity_provider_spec.rb
|
187
|
+
- spec/lib/indexed_object_spec.rb
|
188
|
+
- spec/lib/response_spec.rb
|
189
|
+
- spec/lib/service_provider_spec.rb
|
190
|
+
- spec/spec_helper.rb
|
191
|
+
has_rdoc:
|