11module Samlr
22 class Assertion
3+ DEFAULT_LOCATION = "/samlp:Response/saml:Assertion"
34 attr_reader :document , :options
45
56 def initialize ( document , options )
@@ -8,38 +9,47 @@ def initialize(document, options)
89 end
910
1011 def verify!
11- verify_assertion !
12+ verify_signature !
1213 verify_conditions! unless skip_conditions?
13- signature . verify! unless signature . missing?
1414
1515 true
1616 end
1717
1818 def location
19- "/samlp:Response/saml:Assertion"
19+ @location ||= begin
20+ verify_signature!
21+
22+ if !signature . missing?
23+ if signature . references . any?
24+ "//saml:Assertion[@ID='#{ signature . references . first . uri } ']"
25+ else
26+ raise SignatureError . new ( "Missing references inside checked signature" )
27+ end
28+ else
29+ DEFAULT_LOCATION
30+ end
31+ end
2032 end
2133
2234 def signature
23- @signature ||= Samlr ::Signature . new ( document , location , options )
35+ @signature ||= Samlr ::Signature . new ( document , DEFAULT_LOCATION , options )
2436 end
2537
2638 def attributes
27- @attributes ||= begin
28- { } . tap do |attrs |
29- assertion . xpath ( "./saml:AttributeStatement/saml:Attribute" , NS_MAP ) . each do |statement |
30- name = statement [ "Name" ]
31- values = statement . xpath ( "./saml:AttributeValue" , NS_MAP )
32-
33- if values . size == 0
34- next
35- elsif values . size == 1
36- value = values . first . text
37- else
38- value = values . map { |value | value . text }
39- end
40-
41- attrs [ name ] = attrs [ name . to_sym ] = value
39+ @attributes ||= { } . tap do |attrs |
40+ assertion . xpath ( "./saml:AttributeStatement/saml:Attribute" , NS_MAP ) . each do |statement |
41+ name = statement [ "Name" ]
42+ values = statement . xpath ( "./saml:AttributeValue" , NS_MAP )
43+
44+ if values . size == 0
45+ next
46+ elsif values . size == 1
47+ value = values . first . text
48+ else
49+ value = values . map { |value | value . text }
4250 end
51+
52+ attrs [ name ] = attrs [ name . to_sym ] = value
4353 end
4454 end
4555 end
@@ -54,6 +64,13 @@ def assertion
5464 @assertion ||= document . at ( location , NS_MAP )
5565 end
5666
67+ def verify_signature!
68+ verify_assertion!
69+ signature . verify! unless signature . missing?
70+
71+ true
72+ end
73+
5774 def skip_conditions?
5875 !!options [ :skip_conditions ]
5976 end
@@ -67,7 +84,7 @@ def verify_conditions!
6784 end
6885
6986 def verify_assertion!
70- assertion_count = document . xpath ( location , NS_MAP ) . size
87+ assertion_count = document . xpath ( DEFAULT_LOCATION , NS_MAP ) . size
7188
7289 if assertion_count == 0
7390 raise Samlr ::FormatError . new ( "Invalid SAML response: assertion missing" )
0 commit comments