ruby-saml 0.8.5 → 0.8.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.
Potentially problematic release.
This version of ruby-saml might be problematic. Click here for more details.
- checksums.yaml +7 -7
- data/lib/onelogin/ruby-saml/attributes.rb +128 -0
- data/lib/onelogin/ruby-saml/response.rb +60 -17
- data/lib/onelogin/ruby-saml/version.rb +1 -1
- data/lib/ruby-saml.rb +1 -0
- data/test/response_test.rb +98 -1
- data/test/responses/response_with_multiple_attribute_statements.xml +72 -0
- data/test/responses/response_with_multiple_attribute_values.xml +67 -0
- data/test/test_helper.rb +8 -0
- metadata +53 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
5
|
-
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 57e7a2eb4f514972244fc12215e6586386fb5fe3
|
4
|
+
data.tar.gz: cf05522f6c29de7ae71c30407a93ee2cfe5926b9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 039cc1a41f64dd95707f441afc2015bc44948944fa0356ead52280d5420ebc314d9b004f3e048694356aa40b36546c0a3a98e2f8e4c98f79079b199629f4872f
|
7
|
+
data.tar.gz: 57a46834046c71fce8a1845487e6dfb53fb6b9dadac4d411462e2e2731c8457b162be13563fbad92f3f15e7639916c59e8a266842d018191c40cbfb5f77038c6
|
@@ -0,0 +1,128 @@
|
|
1
|
+
module OneLogin
|
2
|
+
module RubySaml
|
3
|
+
|
4
|
+
# SAML2 Attributes. Parse the Attributes from the AttributeStatement of the SAML Response.
|
5
|
+
#
|
6
|
+
class Attributes
|
7
|
+
include Enumerable
|
8
|
+
|
9
|
+
attr_reader :attributes
|
10
|
+
|
11
|
+
# By default Attributes#[] is backwards compatible and
|
12
|
+
# returns only the first value for the attribute
|
13
|
+
# Setting this to `false` returns all values for an attribute
|
14
|
+
@@single_value_compatibility = true
|
15
|
+
|
16
|
+
# @return [Boolean] Get current status of backwards compatibility mode.
|
17
|
+
#
|
18
|
+
def self.single_value_compatibility
|
19
|
+
@@single_value_compatibility
|
20
|
+
end
|
21
|
+
|
22
|
+
# Sets the backwards compatibility mode on/off.
|
23
|
+
# @param value [Boolean]
|
24
|
+
#
|
25
|
+
def self.single_value_compatibility=(value)
|
26
|
+
@@single_value_compatibility = value
|
27
|
+
end
|
28
|
+
|
29
|
+
# @param attrs [Hash] The +attrs+ must be a Hash with attribute names as keys and **arrays** as values:
|
30
|
+
# Attributes.new({
|
31
|
+
# 'name' => ['value1', 'value2'],
|
32
|
+
# 'mail' => ['value1'],
|
33
|
+
# })
|
34
|
+
#
|
35
|
+
def initialize(attrs = {})
|
36
|
+
@attributes = attrs
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
# Iterate over all attributes
|
41
|
+
#
|
42
|
+
def each
|
43
|
+
attributes.each{|name, values| yield name, values}
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
# Test attribute presence by name
|
48
|
+
# @param name [String] The attribute name to be checked
|
49
|
+
#
|
50
|
+
def include?(name)
|
51
|
+
attributes.has_key?(canonize_name(name))
|
52
|
+
end
|
53
|
+
|
54
|
+
# Return first value for an attribute
|
55
|
+
# @param name [String] The attribute name
|
56
|
+
# @return [String] The value (First occurrence)
|
57
|
+
#
|
58
|
+
def single(name)
|
59
|
+
attributes[canonize_name(name)].first if include?(name)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Return all values for an attribute
|
63
|
+
# @param name [String] The attribute name
|
64
|
+
# @return [Array] Values of the attribute
|
65
|
+
#
|
66
|
+
def multi(name)
|
67
|
+
attributes[canonize_name(name)]
|
68
|
+
end
|
69
|
+
|
70
|
+
# Retrieve attribute value(s)
|
71
|
+
# @param name [String] The attribute name
|
72
|
+
# @return [String|Array] Depending on the single value compatibility status this returns:
|
73
|
+
# - First value if single_value_compatibility = true
|
74
|
+
# response.attributes['mail'] # => 'user@example.com'
|
75
|
+
# - All values if single_value_compatibility = false
|
76
|
+
# response.attributes['mail'] # => ['user@example.com','user@example.net']
|
77
|
+
#
|
78
|
+
def [](name)
|
79
|
+
self.class.single_value_compatibility ? single(canonize_name(name)) : multi(canonize_name(name))
|
80
|
+
end
|
81
|
+
|
82
|
+
# @return [Array] Return all attributes as an array
|
83
|
+
#
|
84
|
+
def all
|
85
|
+
attributes
|
86
|
+
end
|
87
|
+
|
88
|
+
# @param name [String] The attribute name
|
89
|
+
# @param values [Array] The values
|
90
|
+
#
|
91
|
+
def set(name, values)
|
92
|
+
attributes[canonize_name(name)] = values
|
93
|
+
end
|
94
|
+
alias_method :[]=, :set
|
95
|
+
|
96
|
+
# @param name [String] The attribute name
|
97
|
+
# @param values [Array] The values
|
98
|
+
#
|
99
|
+
def add(name, values = [])
|
100
|
+
attributes[canonize_name(name)] ||= []
|
101
|
+
attributes[canonize_name(name)] += Array(values)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Make comparable to another Attributes collection based on attributes
|
105
|
+
# @param other [Attributes] An Attributes object to compare with
|
106
|
+
# @return [Boolean] True if are contains the same attributes and values
|
107
|
+
#
|
108
|
+
def ==(other)
|
109
|
+
if other.is_a?(Attributes)
|
110
|
+
all == other.all
|
111
|
+
else
|
112
|
+
super
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
protected
|
117
|
+
|
118
|
+
# stringifies all names so both 'email' and :email return the same result
|
119
|
+
# @param name [String] The attribute name
|
120
|
+
# @return [String] stringified name
|
121
|
+
#
|
122
|
+
def canonize_name(name)
|
123
|
+
name.to_s
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require "xml_security"
|
2
2
|
require "time"
|
3
3
|
require "nokogiri"
|
4
|
+
require 'onelogin/ruby-saml/attributes'
|
4
5
|
|
5
6
|
# Only supports SAML 2.0
|
6
7
|
module OneLogin
|
@@ -48,26 +49,48 @@ module OneLogin
|
|
48
49
|
end
|
49
50
|
end
|
50
51
|
|
51
|
-
#
|
52
|
+
# Gets the Attributes from the AttributeStatement element.
|
53
|
+
#
|
54
|
+
# All attributes can be iterated over +attributes.each+ or returned as array by +attributes.all+
|
55
|
+
# For backwards compatibility ruby-saml returns by default only the first value for a given attribute with
|
56
|
+
# attributes['name']
|
57
|
+
# To get all of the attributes, use:
|
58
|
+
# attributes.multi('name')
|
59
|
+
# Or turn off the compatibility:
|
60
|
+
# OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
61
|
+
# Now this will return an array:
|
62
|
+
# attributes['name']
|
63
|
+
#
|
64
|
+
# @return [Attributes] OneLogin::RubySaml::Attributes enumerable collection.
|
65
|
+
#
|
52
66
|
def attributes
|
53
67
|
@attr_statements ||= begin
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
+
attributes = Attributes.new
|
69
|
+
|
70
|
+
stmt_elements = xpath_from_signed_assertion('/a:AttributeStatement')
|
71
|
+
stmt_elements.each do |stmt_element|
|
72
|
+
stmt_element.elements.each do |attr_element|
|
73
|
+
name = attr_element.attributes["Name"]
|
74
|
+
values = attr_element.elements.collect{|e|
|
75
|
+
if (e.elements.nil? || e.elements.size == 0)
|
76
|
+
# SAMLCore requires that nil AttributeValues MUST contain xsi:nil XML attribute set to "true" or "1"
|
77
|
+
# otherwise the value is to be regarded as empty.
|
78
|
+
["true", "1"].include?(e.attributes['xsi:nil']) ? nil : Utils.element_text(e)
|
79
|
+
# explicitly support saml2:NameID with saml2:NameQualifier if supplied in attributes
|
80
|
+
# this is useful for allowing eduPersonTargetedId to be passed as an opaque identifier to use to
|
81
|
+
# identify the subject in an SP rather than email or other less opaque attributes
|
82
|
+
# NameQualifier, if present is prefixed with a "/" to the value
|
83
|
+
else
|
84
|
+
REXML::XPath.match(e,'a:NameID', { "a" => ASSERTION }).collect{|n|
|
85
|
+
(n.attributes['NameQualifier'] ? n.attributes['NameQualifier'] +"/" : '') + Utils.element_text(n)
|
86
|
+
}
|
87
|
+
end
|
88
|
+
}
|
89
|
+
|
90
|
+
attributes.add(name, values.flatten)
|
91
|
+
end
|
68
92
|
end
|
69
|
-
|
70
|
-
result
|
93
|
+
attributes
|
71
94
|
end
|
72
95
|
end
|
73
96
|
|
@@ -166,6 +189,26 @@ module OneLogin
|
|
166
189
|
node
|
167
190
|
end
|
168
191
|
|
192
|
+
# Extracts all the appearances that matchs the subelt (pattern)
|
193
|
+
# Search on any Assertion that is signed, or has a Response parent signed
|
194
|
+
# @param subelt [String] The XPath pattern
|
195
|
+
# @return [Array of REXML::Element] Return all matches
|
196
|
+
#
|
197
|
+
def xpath_from_signed_assertion(subelt=nil)
|
198
|
+
node = REXML::XPath.match(
|
199
|
+
document,
|
200
|
+
"/p:Response/a:Assertion[@ID=$id]#{subelt}",
|
201
|
+
{ "p" => PROTOCOL, "a" => ASSERTION },
|
202
|
+
{ 'id' => document.signed_element_id }
|
203
|
+
)
|
204
|
+
node.concat( REXML::XPath.match(
|
205
|
+
document,
|
206
|
+
"/p:Response[@ID=$id]/a:Assertion#{subelt}",
|
207
|
+
{ "p" => PROTOCOL, "a" => ASSERTION },
|
208
|
+
{ 'id' => document.signed_element_id }
|
209
|
+
))
|
210
|
+
end
|
211
|
+
|
169
212
|
def get_fingerprint
|
170
213
|
if settings.idp_cert
|
171
214
|
cert = OpenSSL::X509::Certificate.new(settings.idp_cert)
|
data/lib/ruby-saml.rb
CHANGED
data/test/response_test.rb
CHANGED
@@ -229,7 +229,12 @@ class RubySamlTest < Test::Unit::TestCase
|
|
229
229
|
|
230
230
|
should "not raise on responses without attributes" do
|
231
231
|
response = OneLogin::RubySaml::Response.new(response_document_4)
|
232
|
-
assert_equal
|
232
|
+
assert_equal OneLogin::RubySaml::Attributes.new, response.attributes
|
233
|
+
end
|
234
|
+
|
235
|
+
should "extract attributes from all AttributeStatement tags" do
|
236
|
+
assert_equal "smith", response_with_multiple_attribute_statements.attributes[:surname]
|
237
|
+
assert_equal "bob", response_with_multiple_attribute_statements.attributes[:firstname]
|
233
238
|
end
|
234
239
|
end
|
235
240
|
|
@@ -270,5 +275,97 @@ class RubySamlTest < Test::Unit::TestCase
|
|
270
275
|
assert_equal($evalled, nil)
|
271
276
|
end
|
272
277
|
end
|
278
|
+
|
279
|
+
context "#multiple values" do
|
280
|
+
should "extract single value as string" do
|
281
|
+
assert_equal "demo", response_multiple_attr_values.attributes[:uid]
|
282
|
+
end
|
283
|
+
|
284
|
+
should "extract single value as string in compatibility mode off" do
|
285
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
286
|
+
assert_equal ["demo"], response_multiple_attr_values.attributes[:uid]
|
287
|
+
# classes are not reloaded between tests so restore default
|
288
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
289
|
+
end
|
290
|
+
|
291
|
+
should "extract first of multiple values as string for b/w compatibility" do
|
292
|
+
assert_equal 'value1', response_multiple_attr_values.attributes[:another_value]
|
293
|
+
end
|
294
|
+
|
295
|
+
should "extract first of multiple values as string for b/w compatibility in compatibility mode off" do
|
296
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
297
|
+
assert_equal ['value1', 'value2'], response_multiple_attr_values.attributes[:another_value]
|
298
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
299
|
+
end
|
300
|
+
|
301
|
+
should "return array with all attributes when asked in XML order" do
|
302
|
+
assert_equal ['value1', 'value2'], response_multiple_attr_values.attributes.multi(:another_value)
|
303
|
+
end
|
304
|
+
|
305
|
+
should "return array with all attributes when asked in XML order in compatibility mode off" do
|
306
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
307
|
+
assert_equal ['value1', 'value2'], response_multiple_attr_values.attributes.multi(:another_value)
|
308
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
309
|
+
end
|
310
|
+
|
311
|
+
should "return first of multiple values when multiple Attribute tags in XML" do
|
312
|
+
assert_equal 'role1', response_multiple_attr_values.attributes[:role]
|
313
|
+
end
|
314
|
+
|
315
|
+
should "return first of multiple values when multiple Attribute tags in XML in compatibility mode off" do
|
316
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
317
|
+
assert_equal ['role1', 'role2', 'role3'], response_multiple_attr_values.attributes[:role]
|
318
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
319
|
+
end
|
320
|
+
|
321
|
+
should "return all of multiple values in reverse order when multiple Attribute tags in XML" do
|
322
|
+
assert_equal ['role1', 'role2', 'role3'], response_multiple_attr_values.attributes.multi(:role)
|
323
|
+
end
|
324
|
+
|
325
|
+
should "return all of multiple values in reverse order when multiple Attribute tags in XML in compatibility mode off" do
|
326
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
327
|
+
assert_equal ['role1', 'role2', 'role3'], response_multiple_attr_values.attributes.multi(:role)
|
328
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
329
|
+
end
|
330
|
+
|
331
|
+
should "return all of multiple values when multiple Attribute tags in multiple AttributeStatement tags" do
|
332
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
333
|
+
assert_equal ['role1', 'role2', 'role3'], response_with_multiple_attribute_statements.attributes.multi(:role)
|
334
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
335
|
+
end
|
336
|
+
|
337
|
+
should "return nil value correctly" do
|
338
|
+
assert_nil response_multiple_attr_values.attributes[:attribute_with_nil_value]
|
339
|
+
end
|
340
|
+
|
341
|
+
should "return nil value correctly when not in compatibility mode off" do
|
342
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
343
|
+
assert_equal [nil], response_multiple_attr_values.attributes[:attribute_with_nil_value]
|
344
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
345
|
+
end
|
346
|
+
|
347
|
+
should "return multiple values including nil and empty string" do
|
348
|
+
response = OneLogin::RubySaml::Response.new(fixture(:response_with_multiple_attribute_values))
|
349
|
+
assert_equal ["", "valuePresent", nil, nil], response.attributes.multi(:attribute_with_nils_and_empty_strings)
|
350
|
+
end
|
351
|
+
|
352
|
+
should "return multiple values from [] when not in compatibility mode off" do
|
353
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
354
|
+
assert_equal ["", "valuePresent", nil, nil], response_multiple_attr_values.attributes[:attribute_with_nils_and_empty_strings]
|
355
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
356
|
+
end
|
357
|
+
|
358
|
+
should "check what happens when trying retrieve attribute that does not exists" do
|
359
|
+
assert_equal nil, response_multiple_attr_values.attributes[:attribute_not_exists]
|
360
|
+
assert_equal nil, response_multiple_attr_values.attributes.single(:attribute_not_exists)
|
361
|
+
assert_equal nil, response_multiple_attr_values.attributes.multi(:attribute_not_exists)
|
362
|
+
|
363
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = false
|
364
|
+
assert_equal nil, response_multiple_attr_values.attributes[:attribute_not_exists]
|
365
|
+
assert_equal nil, response_multiple_attr_values.attributes.single(:attribute_not_exists)
|
366
|
+
assert_equal nil, response_multiple_attr_values.attributes.multi(:attribute_not_exists)
|
367
|
+
OneLogin::RubySaml::Attributes.single_value_compatibility = true
|
368
|
+
end
|
369
|
+
end
|
273
370
|
end
|
274
371
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
<samlp:Response xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="GOSAMLR12901174571794" Version="2.0" IssueInstant="2010-11-18T21:57:37Z" Destination="{recipient}">
|
2
|
+
<samlp:Status>
|
3
|
+
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status>
|
4
|
+
<saml:Assertion xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Version="2.0" ID="pfxa46574df-b3b0-a06a-23c8-636413198772" IssueInstant="2010-11-18T21:57:37Z">
|
5
|
+
<saml:Issuer>https://app.onelogin.com/saml/metadata/13590</saml:Issuer>
|
6
|
+
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
7
|
+
<ds:SignedInfo>
|
8
|
+
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
9
|
+
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
|
10
|
+
<ds:Reference URI="#pfxa46574df-b3b0-a06a-23c8-636413198772">
|
11
|
+
<ds:Transforms>
|
12
|
+
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
13
|
+
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
14
|
+
</ds:Transforms>
|
15
|
+
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
|
16
|
+
<ds:DigestValue>pJQ7MS/ek4KRRWGmv/H43ReHYMs=</ds:DigestValue>
|
17
|
+
</ds:Reference>
|
18
|
+
</ds:SignedInfo>
|
19
|
+
<ds:SignatureValue>yiveKcPdDpuDNj6shrQ3ABwr/cA3CryD2phG/xLZszKWxU5/mlaKt8ewbZOdKKvtOs2pHBy5Dua3k94AF+zxGyel5gOowmoyXJr+AOr+kPO0vli1V8o3hPPUZwRgSX6Q9pS1CqQghKiEasRyylqqJUaPYzmOzOE8/XlMkwiWmO0=</ds:SignatureValue>
|
20
|
+
<ds:KeyInfo>
|
21
|
+
<ds:X509Data>
|
22
|
+
<ds:X509Certificate>MIIBrTCCAaGgAwIBAgIBATADBgEAMGcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRUwEwYDVQQHDAxTYW50YSBNb25pY2ExETAPBgNVBAoMCE9uZUxvZ2luMRkwFwYDVQQDDBBhcHAub25lbG9naW4uY29tMB4XDTEwMDMwOTA5NTg0NVoXDTE1MDMwOTA5NTg0NVowZzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFTATBgNVBAcMDFNhbnRhIE1vbmljYTERMA8GA1UECgwIT25lTG9naW4xGTAXBgNVBAMMEGFwcC5vbmVsb2dpbi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOjSu1fjPy8d5w4QyL1+zd4hIw1Mkkff4WY/TLG8OZkU5YTSWmmHPD5kvYH5uoXS/6qQ81qXpR2wV8CTowZJULg09ddRdRn8Qsqj1FyOC5slE3y2bZ2oFua72of/49fpujnFT6KnQ61CBMqlDoTQqOT62vGJ8nP6MZWvA6sxqud5AgMBAAEwAwYBAAMBAA==</ds:X509Certificate>
|
23
|
+
</ds:X509Data>
|
24
|
+
</ds:KeyInfo>
|
25
|
+
</ds:Signature>
|
26
|
+
<saml:Subject>
|
27
|
+
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">support@onelogin.com</saml:NameID>
|
28
|
+
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
|
29
|
+
<saml:SubjectConfirmationData NotOnOrAfter="2010-11-18T22:02:37Z" Recipient="{recipient}"/></saml:SubjectConfirmation>
|
30
|
+
</saml:Subject>
|
31
|
+
<saml:Conditions NotBefore="2010-11-18T21:52:37Z" NotOnOrAfter="2010-11-18T22:02:37Z">
|
32
|
+
<saml:AudienceRestriction>
|
33
|
+
<saml:Audience>{audience}</saml:Audience>
|
34
|
+
</saml:AudienceRestriction>
|
35
|
+
</saml:Conditions>
|
36
|
+
<saml:AuthnStatement AuthnInstant="2010-11-18T21:57:37Z" SessionNotOnOrAfter="2010-11-19T21:57:37Z" SessionIndex="_531c32d283bdff7e04e487bcdbc4dd8d">
|
37
|
+
<saml:AuthnContext>
|
38
|
+
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
|
39
|
+
</saml:AuthnContext>
|
40
|
+
</saml:AuthnStatement>
|
41
|
+
<saml:AttributeStatement>
|
42
|
+
<saml:Attribute Name="surname">
|
43
|
+
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">smith</saml:AttributeValue>
|
44
|
+
</saml:Attribute>
|
45
|
+
<saml:Attribute Name="another_value">
|
46
|
+
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">value1</saml:AttributeValue>
|
47
|
+
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">value2</saml:AttributeValue>
|
48
|
+
</saml:Attribute>
|
49
|
+
<saml:Attribute Name="role">
|
50
|
+
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">role1</saml:AttributeValue>
|
51
|
+
</saml:Attribute>
|
52
|
+
</saml:AttributeStatement>
|
53
|
+
<saml:AttributeStatement>
|
54
|
+
<saml:Attribute Name="firstname">
|
55
|
+
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">bob</saml:AttributeValue>
|
56
|
+
</saml:Attribute>
|
57
|
+
<saml:Attribute Name="role">
|
58
|
+
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">role2</saml:AttributeValue>
|
59
|
+
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">role3</saml:AttributeValue>
|
60
|
+
</saml:Attribute>
|
61
|
+
<saml:Attribute Name="attribute_with_nil_value">
|
62
|
+
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
|
63
|
+
</saml:Attribute>
|
64
|
+
<saml:Attribute Name="attribute_with_nils_and_empty_strings">
|
65
|
+
<saml:AttributeValue/>
|
66
|
+
<saml:AttributeValue>valuePresent</saml:AttributeValue>
|
67
|
+
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
|
68
|
+
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="1"/>
|
69
|
+
</saml:Attribute>
|
70
|
+
</saml:AttributeStatement>
|
71
|
+
</saml:Assertion>
|
72
|
+
</samlp:Response>
|
@@ -0,0 +1,67 @@
|
|
1
|
+
<samlp:Response xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="GOSAMLR12901174571794" Version="2.0" IssueInstant="2010-11-18T21:57:37Z" Destination="{recipient}">
|
2
|
+
<samlp:Status>
|
3
|
+
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status>
|
4
|
+
<saml:Assertion xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Version="2.0" ID="pfxa46574df-b3b0-a06a-23c8-636413198772" IssueInstant="2010-11-18T21:57:37Z">
|
5
|
+
<saml:Issuer>https://app.onelogin.com/saml/metadata/13590</saml:Issuer>
|
6
|
+
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
7
|
+
<ds:SignedInfo>
|
8
|
+
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
9
|
+
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
|
10
|
+
<ds:Reference URI="#pfxa46574df-b3b0-a06a-23c8-636413198772">
|
11
|
+
<ds:Transforms>
|
12
|
+
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
13
|
+
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
14
|
+
</ds:Transforms>
|
15
|
+
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
|
16
|
+
<ds:DigestValue>pJQ7MS/ek4KRRWGmv/H43ReHYMs=</ds:DigestValue>
|
17
|
+
</ds:Reference>
|
18
|
+
</ds:SignedInfo>
|
19
|
+
<ds:SignatureValue>yiveKcPdDpuDNj6shrQ3ABwr/cA3CryD2phG/xLZszKWxU5/mlaKt8ewbZOdKKvtOs2pHBy5Dua3k94AF+zxGyel5gOowmoyXJr+AOr+kPO0vli1V8o3hPPUZwRgSX6Q9pS1CqQghKiEasRyylqqJUaPYzmOzOE8/XlMkwiWmO0=</ds:SignatureValue>
|
20
|
+
<ds:KeyInfo>
|
21
|
+
<ds:X509Data>
|
22
|
+
<ds:X509Certificate>MIIBrTCCAaGgAwIBAgIBATADBgEAMGcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRUwEwYDVQQHDAxTYW50YSBNb25pY2ExETAPBgNVBAoMCE9uZUxvZ2luMRkwFwYDVQQDDBBhcHAub25lbG9naW4uY29tMB4XDTEwMDMwOTA5NTg0NVoXDTE1MDMwOTA5NTg0NVowZzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFTATBgNVBAcMDFNhbnRhIE1vbmljYTERMA8GA1UECgwIT25lTG9naW4xGTAXBgNVBAMMEGFwcC5vbmVsb2dpbi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOjSu1fjPy8d5w4QyL1+zd4hIw1Mkkff4WY/TLG8OZkU5YTSWmmHPD5kvYH5uoXS/6qQ81qXpR2wV8CTowZJULg09ddRdRn8Qsqj1FyOC5slE3y2bZ2oFua72of/49fpujnFT6KnQ61CBMqlDoTQqOT62vGJ8nP6MZWvA6sxqud5AgMBAAEwAwYBAAMBAA==</ds:X509Certificate>
|
23
|
+
</ds:X509Data>
|
24
|
+
</ds:KeyInfo>
|
25
|
+
</ds:Signature>
|
26
|
+
<saml:Subject>
|
27
|
+
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">support@onelogin.com</saml:NameID>
|
28
|
+
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
|
29
|
+
<saml:SubjectConfirmationData NotOnOrAfter="2010-11-18T22:02:37Z" Recipient="{recipient}"/></saml:SubjectConfirmation>
|
30
|
+
</saml:Subject>
|
31
|
+
<saml:Conditions NotBefore="2010-11-18T21:52:37Z" NotOnOrAfter="2010-11-18T22:02:37Z">
|
32
|
+
<saml:AudienceRestriction>
|
33
|
+
<saml:Audience>{audience}</saml:Audience>
|
34
|
+
</saml:AudienceRestriction>
|
35
|
+
</saml:Conditions>
|
36
|
+
<saml:AuthnStatement AuthnInstant="2010-11-18T21:57:37Z" SessionNotOnOrAfter="2010-11-19T21:57:37Z" SessionIndex="_531c32d283bdff7e04e487bcdbc4dd8d">
|
37
|
+
<saml:AuthnContext>
|
38
|
+
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
|
39
|
+
</saml:AuthnContext>
|
40
|
+
</saml:AuthnStatement>
|
41
|
+
<saml:AttributeStatement>
|
42
|
+
<saml:Attribute Name="uid">
|
43
|
+
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">demo</saml:AttributeValue>
|
44
|
+
</saml:Attribute>
|
45
|
+
<saml:Attribute Name="another_value">
|
46
|
+
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">value1</saml:AttributeValue>
|
47
|
+
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">value2</saml:AttributeValue>
|
48
|
+
</saml:Attribute>
|
49
|
+
<saml:Attribute Name="role">
|
50
|
+
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">role1</saml:AttributeValue>
|
51
|
+
</saml:Attribute>
|
52
|
+
<saml:Attribute Name="role">
|
53
|
+
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">role2</saml:AttributeValue>
|
54
|
+
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">role3</saml:AttributeValue>
|
55
|
+
</saml:Attribute>
|
56
|
+
<saml:Attribute Name="attribute_with_nil_value">
|
57
|
+
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
|
58
|
+
</saml:Attribute>
|
59
|
+
<saml:Attribute Name="attribute_with_nils_and_empty_strings">
|
60
|
+
<saml:AttributeValue/>
|
61
|
+
<saml:AttributeValue>valuePresent</saml:AttributeValue>
|
62
|
+
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
|
63
|
+
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="1"/>
|
64
|
+
</saml:Attribute>
|
65
|
+
</saml:AttributeStatement>
|
66
|
+
</saml:Assertion>
|
67
|
+
</samlp:Response>
|
data/test/test_helper.rb
CHANGED
@@ -71,4 +71,12 @@ class Test::Unit::TestCase
|
|
71
71
|
@signature2 ||= File.read(File.join(File.dirname(__FILE__), 'certificates', 'r1_certificate2_base64'))
|
72
72
|
end
|
73
73
|
|
74
|
+
def response_with_multiple_attribute_statements
|
75
|
+
@response_with_multiple_attribute_statements = OneLogin::RubySaml::Response.new(fixture(:response_with_multiple_attribute_statements))
|
76
|
+
end
|
77
|
+
|
78
|
+
def response_multiple_attr_values
|
79
|
+
@response_multiple_attr_values = OneLogin::RubySaml::Response.new(fixture(:response_with_multiple_attribute_values))
|
80
|
+
end
|
81
|
+
|
74
82
|
end
|
metadata
CHANGED
@@ -1,54 +1,60 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-saml
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.8.6
|
5
5
|
platform: ruby
|
6
|
-
authors:
|
6
|
+
authors:
|
7
7
|
- OneLogin LLC
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
- !ruby/object:Gem::Dependency
|
11
|
+
date: 2019-02-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
15
14
|
name: uuid
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
version: "2.3"
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.3'
|
22
20
|
type: :runtime
|
23
|
-
version_requirements: *id001
|
24
|
-
- !ruby/object:Gem::Dependency
|
25
|
-
name: nokogiri
|
26
21
|
prerelease: false
|
27
|
-
|
28
|
-
requirements:
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: nokogiri
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
29
31
|
- - ">="
|
30
|
-
- !ruby/object:Gem::Version
|
32
|
+
- !ruby/object:Gem::Version
|
31
33
|
version: 1.5.0
|
32
34
|
type: :runtime
|
33
|
-
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.5.0
|
34
41
|
description: SAML toolkit for Ruby on Rails
|
35
42
|
email: support@onelogin.com
|
36
43
|
executables: []
|
37
|
-
|
38
44
|
extensions: []
|
39
|
-
|
40
|
-
extra_rdoc_files:
|
45
|
+
extra_rdoc_files:
|
41
46
|
- LICENSE
|
42
47
|
- README.md
|
43
|
-
files:
|
44
|
-
- .document
|
45
|
-
- .gitignore
|
46
|
-
- .travis.yml
|
48
|
+
files:
|
49
|
+
- ".document"
|
50
|
+
- ".gitignore"
|
51
|
+
- ".travis.yml"
|
47
52
|
- Gemfile
|
48
53
|
- LICENSE
|
49
54
|
- README.md
|
50
55
|
- Rakefile
|
51
56
|
- changelog.md
|
57
|
+
- lib/onelogin/ruby-saml/attributes.rb
|
52
58
|
- lib/onelogin/ruby-saml/authrequest.rb
|
53
59
|
- lib/onelogin/ruby-saml/logging.rb
|
54
60
|
- lib/onelogin/ruby-saml/logoutrequest.rb
|
@@ -89,6 +95,8 @@ files:
|
|
89
95
|
- test/responses/response_node_text_attack.xml.base64
|
90
96
|
- test/responses/response_with_ampersands.xml
|
91
97
|
- test/responses/response_with_ampersands.xml.base64
|
98
|
+
- test/responses/response_with_multiple_attribute_statements.xml
|
99
|
+
- test/responses/response_with_multiple_attribute_values.xml
|
92
100
|
- test/responses/simple_saml_php.xml
|
93
101
|
- test/responses/starfield_response.xml.base64
|
94
102
|
- test/responses/wrapped_response_2.xml.base64
|
@@ -98,31 +106,29 @@ files:
|
|
98
106
|
- test/xml_security_test.rb
|
99
107
|
homepage: http://github.com/onelogin/ruby-saml
|
100
108
|
licenses: []
|
101
|
-
|
102
109
|
metadata: {}
|
103
|
-
|
104
110
|
post_install_message:
|
105
|
-
rdoc_options:
|
106
|
-
- --charset=UTF-8
|
107
|
-
require_paths:
|
111
|
+
rdoc_options:
|
112
|
+
- "--charset=UTF-8"
|
113
|
+
require_paths:
|
108
114
|
- lib
|
109
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
110
|
-
requirements:
|
111
|
-
-
|
112
|
-
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
115
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
118
125
|
requirements: []
|
119
|
-
|
120
126
|
rubyforge_project: http://www.rubygems.org/gems/ruby-saml
|
121
|
-
rubygems_version: 2.
|
127
|
+
rubygems_version: 2.5.2.1
|
122
128
|
signing_key:
|
123
129
|
specification_version: 4
|
124
130
|
summary: SAML Ruby Tookit
|
125
|
-
test_files:
|
131
|
+
test_files:
|
126
132
|
- test/certificates/certificate1
|
127
133
|
- test/certificates/r1_certificate2_base64
|
128
134
|
- test/logoutrequest_test.rb
|
@@ -146,6 +152,8 @@ test_files:
|
|
146
152
|
- test/responses/response_node_text_attack.xml.base64
|
147
153
|
- test/responses/response_with_ampersands.xml
|
148
154
|
- test/responses/response_with_ampersands.xml.base64
|
155
|
+
- test/responses/response_with_multiple_attribute_statements.xml
|
156
|
+
- test/responses/response_with_multiple_attribute_values.xml
|
149
157
|
- test/responses/simple_saml_php.xml
|
150
158
|
- test/responses/starfield_response.xml.base64
|
151
159
|
- test/responses/wrapped_response_2.xml.base64
|