ruby-saml-uppercase 0.5.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/.document +5 -0
  2. data/.gitignore +10 -0
  3. data/.travis.yml +5 -0
  4. data/Gemfile +12 -0
  5. data/LICENSE +19 -0
  6. data/README.md +126 -0
  7. data/Rakefile +41 -0
  8. data/lib/onelogin/ruby-saml/authrequest.rb +79 -0
  9. data/lib/onelogin/ruby-saml/logging.rb +26 -0
  10. data/lib/onelogin/ruby-saml/logoutrequest.rb +82 -0
  11. data/lib/onelogin/ruby-saml/logoutresponse.rb +160 -0
  12. data/lib/onelogin/ruby-saml/metadata.rb +47 -0
  13. data/lib/onelogin/ruby-saml/response.rb +195 -0
  14. data/lib/onelogin/ruby-saml/settings.rb +19 -0
  15. data/lib/onelogin/ruby-saml/validation_error.rb +7 -0
  16. data/lib/onelogin/ruby-saml/version.rb +5 -0
  17. data/lib/ruby-saml.rb +9 -0
  18. data/lib/schemas/saml20assertion_schema.xsd +283 -0
  19. data/lib/schemas/saml20protocol_schema.xsd +302 -0
  20. data/lib/schemas/xenc_schema.xsd +146 -0
  21. data/lib/schemas/xmldsig_schema.xsd +318 -0
  22. data/lib/xml_security.rb +168 -0
  23. data/ruby-saml.gemspec +29 -0
  24. data/test/certificates/certificate1 +12 -0
  25. data/test/logoutrequest_test.rb +111 -0
  26. data/test/logoutresponse_test.rb +116 -0
  27. data/test/request_test.rb +53 -0
  28. data/test/response_test.rb +219 -0
  29. data/test/responses/adfs_response_sha1.xml +46 -0
  30. data/test/responses/adfs_response_sha256.xml +46 -0
  31. data/test/responses/adfs_response_sha384.xml +46 -0
  32. data/test/responses/adfs_response_sha512.xml +46 -0
  33. data/test/responses/logoutresponse_fixtures.rb +67 -0
  34. data/test/responses/no_signature_ns.xml +48 -0
  35. data/test/responses/open_saml_response.xml +56 -0
  36. data/test/responses/response1.xml.base64 +1 -0
  37. data/test/responses/response2.xml.base64 +79 -0
  38. data/test/responses/response3.xml.base64 +66 -0
  39. data/test/responses/response4.xml.base64 +93 -0
  40. data/test/responses/response5.xml.base64 +102 -0
  41. data/test/responses/response_with_ampersands.xml +139 -0
  42. data/test/responses/response_with_ampersands.xml.base64 +93 -0
  43. data/test/responses/simple_saml_php.xml +71 -0
  44. data/test/responses/wrapped_response_2.xml.base64 +150 -0
  45. data/test/settings_test.rb +44 -0
  46. data/test/test_helper.rb +66 -0
  47. data/test/xml_security_test.rb +123 -0
  48. metadata +166 -0
@@ -0,0 +1,47 @@
1
+ require "rexml/document"
2
+ require "rexml/xpath"
3
+ require "uri"
4
+
5
+ # Class to return SP metadata based on the settings requested.
6
+ # Return this XML in a controller, then give that URL to the the
7
+ # IdP administrator. The IdP will poll the URL and your settings
8
+ # will be updated automatically
9
+ module Onelogin
10
+ module Saml
11
+ include REXML
12
+ class Metadata
13
+ def generate(settings)
14
+ meta_doc = REXML::Document.new
15
+ root = meta_doc.add_element "md:EntityDescriptor", {
16
+ "xmlns:md" => "urn:oasis:names:tc:SAML:2.0:metadata"
17
+ }
18
+ sp_sso = root.add_element "md:SPSSODescriptor", {
19
+ "protocolSupportEnumeration" => "urn:oasis:names:tc:SAML:2.0:protocol"
20
+ }
21
+ if settings.issuer != nil
22
+ root.attributes["entityID"] = settings.issuer
23
+ end
24
+ if settings.name_identifier_format != nil
25
+ name_id = sp_sso.add_element "md:NameIDFormat"
26
+ name_id.text = settings.name_identifier_format
27
+ end
28
+ if settings.assertion_consumer_service_url != nil
29
+ sp_sso.add_element "md:AssertionConsumerService", {
30
+ # Add this as a setting to create different bindings?
31
+ "Binding" => "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
32
+ "Location" => settings.assertion_consumer_service_url
33
+ }
34
+ end
35
+ meta_doc << REXML::XMLDecl.new
36
+ ret = ""
37
+ # pretty print the XML so IdP administrators can easily see what the SP supports
38
+ meta_doc.write(ret, 1)
39
+
40
+ Logging.debug "Generated metadata:\n#{ret}"
41
+
42
+ return ret
43
+
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,195 @@
1
+ require "xml_security"
2
+ require "time"
3
+ require "nokogiri"
4
+
5
+ # Only supports SAML 2.0
6
+ module Onelogin
7
+ module Saml
8
+
9
+ class Response
10
+ ASSERTION = "urn:oasis:names:tc:SAML:2.0:assertion"
11
+ PROTOCOL = "urn:oasis:names:tc:SAML:2.0:protocol"
12
+ DSIG = "http://www.w3.org/2000/09/xmldsig#"
13
+
14
+ attr_accessor :options, :response, :document, :settings
15
+ attr_reader :raw_response
16
+
17
+ def initialize(response, options = {})
18
+ raise ArgumentError.new("Response cannot be nil") if response.nil?
19
+ self.options = options
20
+ @raw_response = response
21
+
22
+ parse_response!
23
+ end
24
+
25
+ def parse_response!
26
+ @response = if @raw_response =~ /^</
27
+ @raw_response
28
+ else
29
+ Base64.decode64(@raw_response)
30
+ end
31
+
32
+ begin
33
+ self.document = XMLSecurity::SignedDocument.new(@response)
34
+ rescue REXML::ParseException => e
35
+ raise e
36
+ end
37
+ end
38
+
39
+ def is_valid?
40
+ validate
41
+ end
42
+
43
+ def validate!
44
+ validate(false)
45
+ end
46
+
47
+ # The value of the user identifier as designated by the initialization request response
48
+ def name_id
49
+ @name_id ||= begin
50
+ node = REXML::XPath.first(document, "/p:Response/a:Assertion[@ID='#{document.signed_element_id}']/a:Subject/a:NameID", { "p" => PROTOCOL, "a" => ASSERTION })
51
+ node ||= REXML::XPath.first(document, "/p:Response[@ID='#{document.signed_element_id}']/a:Assertion/a:Subject/a:NameID", { "p" => PROTOCOL, "a" => ASSERTION })
52
+ node.nil? ? nil : node.text
53
+ end
54
+ end
55
+
56
+ def sessionindex
57
+ @sessionindex ||= begin
58
+ node = REXML::XPath.first(document, "/p:Response/a:Assertion[@ID='#{document.signed_element_id}']/a:AuthnStatement", { "p" => PROTOCOL, "a" => ASSERTION })
59
+ node ||= REXML::XPath.first(document, "/p:Response[@ID='#{document.signed_element_id}']/a:Assertion/a:AuthnStatement", { "p" => PROTOCOL, "a" => ASSERTION })
60
+ node.nil? ? nil : node.attributes['SessionIndex']
61
+ end
62
+ end
63
+
64
+ # A hash of alle the attributes with the response. Assuming there is only one value for each key
65
+ def attributes
66
+ @attr_statements ||= begin
67
+ result = {}
68
+
69
+ stmt_element = REXML::XPath.first(document, "/p:Response/a:Assertion/a:AttributeStatement", { "p" => PROTOCOL, "a" => ASSERTION })
70
+ return {} if stmt_element.nil?
71
+
72
+ stmt_element.elements.each do |attr_element|
73
+ name = attr_element.attributes["Name"]
74
+ value = attr_element.elements.first.text
75
+
76
+ result[name] = value
77
+ end
78
+
79
+ result.keys.each do |key|
80
+ result[key.intern] = result[key]
81
+ end
82
+
83
+ result
84
+ end
85
+ end
86
+
87
+ # When this user session should expire at latest
88
+ def session_expires_at
89
+ @expires_at ||= begin
90
+ node = REXML::XPath.first(document, "/p:Response/a:Assertion/a:AuthnStatement", { "p" => PROTOCOL, "a" => ASSERTION })
91
+ parse_time(node, "SessionNotOnOrAfter")
92
+ end
93
+ end
94
+
95
+ # Checks the status of the response for a "Success" code
96
+ def success?
97
+ @status_code ||= begin
98
+ node = REXML::XPath.first(document, "/p:Response/p:Status/p:StatusCode", { "p" => PROTOCOL, "a" => ASSERTION })
99
+ node.attributes["Value"] == "urn:oasis:names:tc:SAML:2.0:status:Success"
100
+ end
101
+ end
102
+
103
+ # Conditions (if any) for the assertion to run
104
+ def conditions
105
+ @conditions ||= begin
106
+ REXML::XPath.first(document, "/p:Response/a:Assertion[@ID='#{document.signed_element_id}']/a:Conditions", { "p" => PROTOCOL, "a" => ASSERTION })
107
+ end
108
+ end
109
+
110
+ def issuer
111
+ @issuer ||= begin
112
+ node = REXML::XPath.first(document, "/p:Response/a:Issuer", { "p" => PROTOCOL, "a" => ASSERTION })
113
+ node ||= REXML::XPath.first(document, "/p:Response/a:Assertion/a:Issuer", { "p" => PROTOCOL, "a" => ASSERTION })
114
+ node.nil? ? nil : node.text
115
+ end
116
+ end
117
+
118
+ private
119
+
120
+ def validation_error(message)
121
+ raise ValidationError.new(message)
122
+ end
123
+
124
+ def validate(soft = true)
125
+ validate_structure(soft) &&
126
+ validate_response_state(soft) &&
127
+ validate_conditions(soft) &&
128
+ document.validate(get_fingerprint, soft) &&
129
+ success?
130
+ end
131
+
132
+ def validate_structure(soft = true)
133
+ Dir.chdir(File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'schemas'))) do
134
+ @schema = Nokogiri::XML::Schema(IO.read('saml20protocol_schema.xsd'))
135
+ @xml = Nokogiri::XML(self.document.to_s)
136
+ end
137
+ if soft
138
+ @schema.validate(@xml).map{ return false }
139
+ else
140
+ @schema.validate(@xml).map{ |error| raise(Exception.new("#{error.message}\n\n#{@xml.to_s}")) }
141
+ end
142
+ end
143
+
144
+ def validate_response_state(soft = true)
145
+ if response.empty?
146
+ return soft ? false : validation_error("Blank response")
147
+ end
148
+
149
+ if settings.nil?
150
+ return soft ? false : validation_error("No settings on response")
151
+ end
152
+
153
+ if settings.idp_cert_fingerprint.nil? && settings.idp_cert.nil?
154
+ return soft ? false : validation_error("No fingerprint or certificate on settings")
155
+ end
156
+
157
+ true
158
+ end
159
+
160
+ def get_fingerprint
161
+ if settings.idp_cert
162
+ cert = OpenSSL::X509::Certificate.new(settings.idp_cert)
163
+ Digest::SHA1.hexdigest(cert.to_der).upcase.scan(/../).join(":")
164
+ else
165
+ settings.idp_cert_fingerprint
166
+ end
167
+ end
168
+
169
+ def validate_conditions(soft = true)
170
+ return true if conditions.nil?
171
+ return true if options[:skip_conditions]
172
+
173
+ if not_before = parse_time(conditions, "NotBefore")
174
+ if Time.now.utc < not_before
175
+ return soft ? false : validation_error("Current time is earlier than NotBefore condition")
176
+ end
177
+ end
178
+
179
+ if not_on_or_after = parse_time(conditions, "NotOnOrAfter")
180
+ if Time.now.utc >= not_on_or_after
181
+ return soft ? false : validation_error("Current time is on or after NotOnOrAfter condition")
182
+ end
183
+ end
184
+
185
+ true
186
+ end
187
+
188
+ def parse_time(node, attribute)
189
+ if node && node.attributes[attribute]
190
+ Time.parse(node.attributes[attribute])
191
+ end
192
+ end
193
+ end
194
+ end
195
+ end
@@ -0,0 +1,19 @@
1
+ module Onelogin
2
+ module Saml
3
+ class Settings
4
+ def initialize(config = {})
5
+ config.each do |k,v|
6
+ acc = "#{k.to_s}=".to_sym
7
+ self.send(acc, v) if self.respond_to? acc
8
+ end
9
+ end
10
+ attr_accessor :assertion_consumer_service_url, :issuer, :sp_name_qualifier
11
+ attr_accessor :idp_sso_target_url, :idp_cert_fingerprint, :idp_cert, :name_identifier_format
12
+ attr_accessor :authn_context
13
+ attr_accessor :idp_slo_target_url
14
+ attr_accessor :name_identifier_value
15
+ attr_accessor :sessionindex
16
+ attr_accessor :assertion_consumer_logout_service_url
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,7 @@
1
+ module Onelogin
2
+ module Saml
3
+ class ValidationError < Exception
4
+ end
5
+ end
6
+ end
7
+
@@ -0,0 +1,5 @@
1
+ module Onelogin
2
+ module Saml
3
+ VERSION = '0.5.3.4'
4
+ end
5
+ end
data/lib/ruby-saml.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'onelogin/ruby-saml/logging'
2
+ require 'onelogin/ruby-saml/authrequest'
3
+ require 'onelogin/ruby-saml/logoutrequest'
4
+ require 'onelogin/ruby-saml/logoutresponse'
5
+ require 'onelogin/ruby-saml/response'
6
+ require 'onelogin/ruby-saml/settings'
7
+ require 'onelogin/ruby-saml/validation_error'
8
+ require 'onelogin/ruby-saml/metadata'
9
+ require 'onelogin/ruby-saml/version'
@@ -0,0 +1,283 @@
1
+ <?xml version="1.0" encoding="US-ASCII"?>
2
+ <schema
3
+ targetNamespace="urn:oasis:names:tc:SAML:2.0:assertion"
4
+ xmlns="http://www.w3.org/2001/XMLSchema"
5
+ xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
6
+ xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
7
+ xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
8
+ elementFormDefault="unqualified"
9
+ attributeFormDefault="unqualified"
10
+ blockDefault="substitution"
11
+ version="2.0">
12
+ <import namespace="http://www.w3.org/2000/09/xmldsig#"
13
+ schemaLocation="xmldsig_schema.xsd"/>
14
+ <import namespace="http://www.w3.org/2001/04/xmlenc#"
15
+ schemaLocation="xenc_schema.xsd"/>
16
+ <annotation>
17
+ <documentation>
18
+ Document identifier: saml-schema-assertion-2.0
19
+ Location: http://docs.oasis-open.org/security/saml/v2.0/
20
+ Revision history:
21
+ V1.0 (November, 2002):
22
+ Initial Standard Schema.
23
+ V1.1 (September, 2003):
24
+ Updates within the same V1.0 namespace.
25
+ V2.0 (March, 2005):
26
+ New assertion schema for SAML V2.0 namespace.
27
+ </documentation>
28
+ </annotation>
29
+ <attributeGroup name="IDNameQualifiers">
30
+ <attribute name="NameQualifier" type="string" use="optional"/>
31
+ <attribute name="SPNameQualifier" type="string" use="optional"/>
32
+ </attributeGroup>
33
+ <element name="BaseID" type="saml:BaseIDAbstractType"/>
34
+ <complexType name="BaseIDAbstractType" abstract="true">
35
+ <attributeGroup ref="saml:IDNameQualifiers"/>
36
+ </complexType>
37
+ <element name="NameID" type="saml:NameIDType"/>
38
+ <complexType name="NameIDType">
39
+ <simpleContent>
40
+ <extension base="string">
41
+ <attributeGroup ref="saml:IDNameQualifiers"/>
42
+ <attribute name="Format" type="anyURI" use="optional"/>
43
+ <attribute name="SPProvidedID" type="string" use="optional"/>
44
+ </extension>
45
+ </simpleContent>
46
+ </complexType>
47
+ <complexType name="EncryptedElementType">
48
+ <sequence>
49
+ <element ref="xenc:EncryptedData"/>
50
+ <element ref="xenc:EncryptedKey" minOccurs="0" maxOccurs="unbounded"/>
51
+ </sequence>
52
+ </complexType>
53
+ <element name="EncryptedID" type="saml:EncryptedElementType"/>
54
+ <element name="Issuer" type="saml:NameIDType"/>
55
+ <element name="AssertionIDRef" type="NCName"/>
56
+ <element name="AssertionURIRef" type="anyURI"/>
57
+ <element name="Assertion" type="saml:AssertionType"/>
58
+ <complexType name="AssertionType">
59
+ <sequence>
60
+ <element ref="saml:Issuer"/>
61
+ <element ref="ds:Signature" minOccurs="0"/>
62
+ <element ref="saml:Subject" minOccurs="0"/>
63
+ <element ref="saml:Conditions" minOccurs="0"/>
64
+ <element ref="saml:Advice" minOccurs="0"/>
65
+ <choice minOccurs="0" maxOccurs="unbounded">
66
+ <element ref="saml:Statement"/>
67
+ <element ref="saml:AuthnStatement"/>
68
+ <element ref="saml:AuthzDecisionStatement"/>
69
+ <element ref="saml:AttributeStatement"/>
70
+ </choice>
71
+ </sequence>
72
+ <attribute name="Version" type="string" use="required"/>
73
+ <attribute name="ID" type="ID" use="required"/>
74
+ <attribute name="IssueInstant" type="dateTime" use="required"/>
75
+ </complexType>
76
+ <element name="Subject" type="saml:SubjectType"/>
77
+ <complexType name="SubjectType">
78
+ <choice>
79
+ <sequence>
80
+ <choice>
81
+ <element ref="saml:BaseID"/>
82
+ <element ref="saml:NameID"/>
83
+ <element ref="saml:EncryptedID"/>
84
+ </choice>
85
+ <element ref="saml:SubjectConfirmation" minOccurs="0" maxOccurs="unbounded"/>
86
+ </sequence>
87
+ <element ref="saml:SubjectConfirmation" maxOccurs="unbounded"/>
88
+ </choice>
89
+ </complexType>
90
+ <element name="SubjectConfirmation" type="saml:SubjectConfirmationType"/>
91
+ <complexType name="SubjectConfirmationType">
92
+ <sequence>
93
+ <choice minOccurs="0">
94
+ <element ref="saml:BaseID"/>
95
+ <element ref="saml:NameID"/>
96
+ <element ref="saml:EncryptedID"/>
97
+ </choice>
98
+ <element ref="saml:SubjectConfirmationData" minOccurs="0"/>
99
+ </sequence>
100
+ <attribute name="Method" type="anyURI" use="required"/>
101
+ </complexType>
102
+ <element name="SubjectConfirmationData" type="saml:SubjectConfirmationDataType"/>
103
+ <complexType name="SubjectConfirmationDataType" mixed="true">
104
+ <complexContent>
105
+ <restriction base="anyType">
106
+ <sequence>
107
+ <any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
108
+ </sequence>
109
+ <attribute name="NotBefore" type="dateTime" use="optional"/>
110
+ <attribute name="NotOnOrAfter" type="dateTime" use="optional"/>
111
+ <attribute name="Recipient" type="anyURI" use="optional"/>
112
+ <attribute name="InResponseTo" type="NCName" use="optional"/>
113
+ <attribute name="Address" type="string" use="optional"/>
114
+ <anyAttribute namespace="##other" processContents="lax"/>
115
+ </restriction>
116
+ </complexContent>
117
+ </complexType>
118
+ <complexType name="KeyInfoConfirmationDataType" mixed="false">
119
+ <complexContent>
120
+ <restriction base="saml:SubjectConfirmationDataType">
121
+ <sequence>
122
+ <element ref="ds:KeyInfo" maxOccurs="unbounded"/>
123
+ </sequence>
124
+ </restriction>
125
+ </complexContent>
126
+ </complexType>
127
+ <element name="Conditions" type="saml:ConditionsType"/>
128
+ <complexType name="ConditionsType">
129
+ <choice minOccurs="0" maxOccurs="unbounded">
130
+ <element ref="saml:Condition"/>
131
+ <element ref="saml:AudienceRestriction"/>
132
+ <element ref="saml:OneTimeUse"/>
133
+ <element ref="saml:ProxyRestriction"/>
134
+ </choice>
135
+ <attribute name="NotBefore" type="dateTime" use="optional"/>
136
+ <attribute name="NotOnOrAfter" type="dateTime" use="optional"/>
137
+ </complexType>
138
+ <element name="Condition" type="saml:ConditionAbstractType"/>
139
+ <complexType name="ConditionAbstractType" abstract="true"/>
140
+ <element name="AudienceRestriction" type="saml:AudienceRestrictionType"/>
141
+ <complexType name="AudienceRestrictionType">
142
+ <complexContent>
143
+ <extension base="saml:ConditionAbstractType">
144
+ <sequence>
145
+ <element ref="saml:Audience" maxOccurs="unbounded"/>
146
+ </sequence>
147
+ </extension>
148
+ </complexContent>
149
+ </complexType>
150
+ <element name="Audience" type="anyURI"/>
151
+ <element name="OneTimeUse" type="saml:OneTimeUseType" />
152
+ <complexType name="OneTimeUseType">
153
+ <complexContent>
154
+ <extension base="saml:ConditionAbstractType"/>
155
+ </complexContent>
156
+ </complexType>
157
+ <element name="ProxyRestriction" type="saml:ProxyRestrictionType"/>
158
+ <complexType name="ProxyRestrictionType">
159
+ <complexContent>
160
+ <extension base="saml:ConditionAbstractType">
161
+ <sequence>
162
+ <element ref="saml:Audience" minOccurs="0" maxOccurs="unbounded"/>
163
+ </sequence>
164
+ <attribute name="Count" type="nonNegativeInteger" use="optional"/>
165
+ </extension>
166
+ </complexContent>
167
+ </complexType>
168
+ <element name="Advice" type="saml:AdviceType"/>
169
+ <complexType name="AdviceType">
170
+ <choice minOccurs="0" maxOccurs="unbounded">
171
+ <element ref="saml:AssertionIDRef"/>
172
+ <element ref="saml:AssertionURIRef"/>
173
+ <element ref="saml:Assertion"/>
174
+ <element ref="saml:EncryptedAssertion"/>
175
+ <any namespace="##other" processContents="lax"/>
176
+ </choice>
177
+ </complexType>
178
+ <element name="EncryptedAssertion" type="saml:EncryptedElementType"/>
179
+ <element name="Statement" type="saml:StatementAbstractType"/>
180
+ <complexType name="StatementAbstractType" abstract="true"/>
181
+ <element name="AuthnStatement" type="saml:AuthnStatementType"/>
182
+ <complexType name="AuthnStatementType">
183
+ <complexContent>
184
+ <extension base="saml:StatementAbstractType">
185
+ <sequence>
186
+ <element ref="saml:SubjectLocality" minOccurs="0"/>
187
+ <element ref="saml:AuthnContext"/>
188
+ </sequence>
189
+ <attribute name="AuthnInstant" type="dateTime" use="required"/>
190
+ <attribute name="SessionIndex" type="string" use="optional"/>
191
+ <attribute name="SessionNotOnOrAfter" type="dateTime" use="optional"/>
192
+ </extension>
193
+ </complexContent>
194
+ </complexType>
195
+ <element name="SubjectLocality" type="saml:SubjectLocalityType"/>
196
+ <complexType name="SubjectLocalityType">
197
+ <attribute name="Address" type="string" use="optional"/>
198
+ <attribute name="DNSName" type="string" use="optional"/>
199
+ </complexType>
200
+ <element name="AuthnContext" type="saml:AuthnContextType"/>
201
+ <complexType name="AuthnContextType">
202
+ <sequence>
203
+ <choice>
204
+ <sequence>
205
+ <element ref="saml:AuthnContextClassRef"/>
206
+ <choice minOccurs="0">
207
+ <element ref="saml:AuthnContextDecl"/>
208
+ <element ref="saml:AuthnContextDeclRef"/>
209
+ </choice>
210
+ </sequence>
211
+ <choice>
212
+ <element ref="saml:AuthnContextDecl"/>
213
+ <element ref="saml:AuthnContextDeclRef"/>
214
+ </choice>
215
+ </choice>
216
+ <element ref="saml:AuthenticatingAuthority" minOccurs="0" maxOccurs="unbounded"/>
217
+ </sequence>
218
+ </complexType>
219
+ <element name="AuthnContextClassRef" type="anyURI"/>
220
+ <element name="AuthnContextDeclRef" type="anyURI"/>
221
+ <element name="AuthnContextDecl" type="anyType"/>
222
+ <element name="AuthenticatingAuthority" type="anyURI"/>
223
+ <element name="AuthzDecisionStatement" type="saml:AuthzDecisionStatementType"/>
224
+ <complexType name="AuthzDecisionStatementType">
225
+ <complexContent>
226
+ <extension base="saml:StatementAbstractType">
227
+ <sequence>
228
+ <element ref="saml:Action" maxOccurs="unbounded"/>
229
+ <element ref="saml:Evidence" minOccurs="0"/>
230
+ </sequence>
231
+ <attribute name="Resource" type="anyURI" use="required"/>
232
+ <attribute name="Decision" type="saml:DecisionType" use="required"/>
233
+ </extension>
234
+ </complexContent>
235
+ </complexType>
236
+ <simpleType name="DecisionType">
237
+ <restriction base="string">
238
+ <enumeration value="Permit"/>
239
+ <enumeration value="Deny"/>
240
+ <enumeration value="Indeterminate"/>
241
+ </restriction>
242
+ </simpleType>
243
+ <element name="Action" type="saml:ActionType"/>
244
+ <complexType name="ActionType">
245
+ <simpleContent>
246
+ <extension base="string">
247
+ <attribute name="Namespace" type="anyURI" use="required"/>
248
+ </extension>
249
+ </simpleContent>
250
+ </complexType>
251
+ <element name="Evidence" type="saml:EvidenceType"/>
252
+ <complexType name="EvidenceType">
253
+ <choice maxOccurs="unbounded">
254
+ <element ref="saml:AssertionIDRef"/>
255
+ <element ref="saml:AssertionURIRef"/>
256
+ <element ref="saml:Assertion"/>
257
+ <element ref="saml:EncryptedAssertion"/>
258
+ </choice>
259
+ </complexType>
260
+ <element name="AttributeStatement" type="saml:AttributeStatementType"/>
261
+ <complexType name="AttributeStatementType">
262
+ <complexContent>
263
+ <extension base="saml:StatementAbstractType">
264
+ <choice maxOccurs="unbounded">
265
+ <element ref="saml:Attribute"/>
266
+ <element ref="saml:EncryptedAttribute"/>
267
+ </choice>
268
+ </extension>
269
+ </complexContent>
270
+ </complexType>
271
+ <element name="Attribute" type="saml:AttributeType"/>
272
+ <complexType name="AttributeType">
273
+ <sequence>
274
+ <element ref="saml:AttributeValue" minOccurs="0" maxOccurs="unbounded"/>
275
+ </sequence>
276
+ <attribute name="Name" type="string" use="required"/>
277
+ <attribute name="NameFormat" type="anyURI" use="optional"/>
278
+ <attribute name="FriendlyName" type="string" use="optional"/>
279
+ <anyAttribute namespace="##other" processContents="lax"/>
280
+ </complexType>
281
+ <element name="AttributeValue" type="anyType" nillable="true"/>
282
+ <element name="EncryptedAttribute" type="saml:EncryptedElementType"/>
283
+ </schema>