ruby-saml 0.8.5 → 0.8.6
Sign up to get free protection for your applications and to get access to all the features.
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
|