saml2 1.0.0

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.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +13 -0
  3. data/app/views/saml2/http_post.html.erb +14 -0
  4. data/lib/saml2.rb +9 -0
  5. data/lib/saml2/assertion.rb +37 -0
  6. data/lib/saml2/attribute.rb +127 -0
  7. data/lib/saml2/attribute/x500.rb +79 -0
  8. data/lib/saml2/attribute_consuming_service.rb +76 -0
  9. data/lib/saml2/authn_request.rb +116 -0
  10. data/lib/saml2/authn_statement.rb +26 -0
  11. data/lib/saml2/base.rb +53 -0
  12. data/lib/saml2/contact.rb +50 -0
  13. data/lib/saml2/endpoint.rb +46 -0
  14. data/lib/saml2/engine.rb +4 -0
  15. data/lib/saml2/entity.rb +84 -0
  16. data/lib/saml2/identity_provider.rb +57 -0
  17. data/lib/saml2/indexed_object.rb +59 -0
  18. data/lib/saml2/key.rb +46 -0
  19. data/lib/saml2/name_id.rb +60 -0
  20. data/lib/saml2/namespaces.rb +21 -0
  21. data/lib/saml2/organization.rb +74 -0
  22. data/lib/saml2/organization_and_contacts.rb +35 -0
  23. data/lib/saml2/profiles.rb +7 -0
  24. data/lib/saml2/response.rb +92 -0
  25. data/lib/saml2/role.rb +53 -0
  26. data/lib/saml2/schemas.rb +18 -0
  27. data/lib/saml2/service_provider.rb +30 -0
  28. data/lib/saml2/sso.rb +36 -0
  29. data/lib/saml2/subject.rb +49 -0
  30. data/lib/saml2/version.rb +3 -0
  31. data/schemas/saml-schema-assertion-2.0.xsd +283 -0
  32. data/schemas/saml-schema-metadata-2.0.xsd +339 -0
  33. data/schemas/saml-schema-protocol-2.0.xsd +302 -0
  34. data/schemas/xenc-schema.xsd +136 -0
  35. data/schemas/xml.xsd +287 -0
  36. data/schemas/xmldsig-core-schema.xsd +309 -0
  37. data/spec/fixtures/authnrequest.xml +12 -0
  38. data/spec/fixtures/calculated.txt +1 -0
  39. data/spec/fixtures/certificate.pem +25 -0
  40. data/spec/fixtures/entities.xml +13 -0
  41. data/spec/fixtures/privatekey.key +27 -0
  42. data/spec/fixtures/response_signed.xml +47 -0
  43. data/spec/fixtures/response_with_attribute_signed.xml +47 -0
  44. data/spec/fixtures/service_provider.xml +79 -0
  45. data/spec/fixtures/xmlsec.txt +1 -0
  46. data/spec/lib/attribute_consuming_service_spec.rb +74 -0
  47. data/spec/lib/attribute_spec.rb +39 -0
  48. data/spec/lib/authn_request_spec.rb +52 -0
  49. data/spec/lib/entity_spec.rb +45 -0
  50. data/spec/lib/identity_provider_spec.rb +23 -0
  51. data/spec/lib/indexed_object_spec.rb +38 -0
  52. data/spec/lib/response_spec.rb +60 -0
  53. data/spec/lib/service_provider_spec.rb +30 -0
  54. data/spec/spec_helper.rb +6 -0
  55. metadata +191 -0
@@ -0,0 +1,21 @@
1
+ module SAML2
2
+ module Namespaces
3
+ DSIG = "http://www.w3.org/2000/09/xmldsig#".freeze
4
+ METADATA = "urn:oasis:names:tc:SAML:2.0:metadata".freeze
5
+ SAML = "urn:oasis:names:tc:SAML:2.0:assertion".freeze
6
+ SAMLP = "urn:oasis:names:tc:SAML:2.0:protocol".freeze
7
+ XENC = "http://www.w3.org/2001/04/xmlenc#".freeze
8
+ XSI = "http://www.w3.org/2001/XMLSchema-instance".freeze
9
+ X500 = "urn:oasis:names:tc:SAML:2.0:profiles:attribute:X500".freeze
10
+
11
+ ALL = {
12
+ 'dsig' => DSIG,
13
+ 'md' => METADATA,
14
+ 'saml' => SAML,
15
+ 'samlp' => SAMLP,
16
+ 'x500' => X500,
17
+ 'xenc' => XENC,
18
+ 'xsi' => XSI
19
+ }.freeze
20
+ end
21
+ end
@@ -0,0 +1,74 @@
1
+ require 'saml2/namespaces'
2
+
3
+ module SAML2
4
+ class Organization
5
+ def self.from_xml(node)
6
+ return nil unless node
7
+
8
+ new(nodes_to_hash(node.xpath('md:OrganizationName', Namespaces::ALL)),
9
+ nodes_to_hash(node.xpath('md:OrganizationDisplayName', Namespaces::ALL)),
10
+ nodes_to_hash(node.xpath('md:OrganizationURL', Namespaces::ALL)))
11
+ end
12
+
13
+ def initialize(name, display_name, url)
14
+ if !name.is_a?(Hash)
15
+ name = { nil => name}
16
+ end
17
+ if !display_name.is_a?(Hash)
18
+ display_name = { nil => display_name }
19
+ end
20
+ if !url.is_a?(Hash)
21
+ url = { nil => url }
22
+ end
23
+
24
+ @name, @display_name, @url = name, display_name, url
25
+ end
26
+
27
+ def name(lang = nil)
28
+ self.class.localized_name(@name, lang)
29
+ end
30
+
31
+ def display_name(lang = nil)
32
+ self.class.localized_name(@display_name, lang)
33
+ end
34
+
35
+ def url(lang = nil)
36
+ self.class.localized_name(@url, lang)
37
+ end
38
+
39
+ def build(builder)
40
+ builder['md'].Organization do |builder|
41
+ self.class.build(builder, @name, 'OrganizationName')
42
+ self.class.build(builder, @display_name, 'OrganizationDisplayName')
43
+ self.class.build(builder, @url, 'OrganizationURL')
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ def self.build(builder, hash, element)
50
+ hash.each do |lang, value|
51
+ builder['md'].__send__(element, value, 'xml:lang' => lang)
52
+ end
53
+ end
54
+
55
+ def self.nodes_to_hash(nodes)
56
+ hash = {}
57
+ nodes.each do |node|
58
+ hash[node['xml:lang'].to_sym] = node.content && node.content.strip
59
+ end
60
+ hash
61
+ end
62
+
63
+ def self.localized_name(hash, lang)
64
+ case lang
65
+ when :all
66
+ hash
67
+ when nil
68
+ !hash.empty? && hash.first.last
69
+ else
70
+ hash[lang.to_sym]
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,35 @@
1
+ require 'saml2/contact'
2
+ require 'saml2/organization'
3
+
4
+ module SAML2
5
+ module OrganizationAndContacts
6
+ attr_writer :organization, :contacts
7
+
8
+ def initialize(node = nil)
9
+ unless node
10
+ @organization = nil
11
+ @contacts = []
12
+ end
13
+ end
14
+
15
+ def organization
16
+ unless instance_variable_defined?(:@organization)
17
+ @organization = Organization.from_xml(@root.at_xpath('md:Organization', Namespaces::ALL))
18
+ end
19
+ @organization
20
+ end
21
+
22
+ def contacts
23
+ @contacts ||= load_object_array(@root, 'md:ContactPerson', Contact)
24
+ end
25
+
26
+ protected
27
+
28
+ def build(builder)
29
+ organization.build(builder) if organization
30
+ contacts.each do |contact|
31
+ contact.build(builder)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,7 @@
1
+ module SAML2
2
+ module Profiles
3
+ # http://docs.oasis-open.org/security/saml/v2.0/saml-profiles-2.0-os.pdf
4
+ WEB_BROWSER_SSO = 'urn:oasis:names:tc:SAML:2.0:profiles:SSO:browser'.freeze
5
+ INTEROPERABLE = 'http://saml2int.org/profile'.freeze
6
+ end
7
+ end
@@ -0,0 +1,92 @@
1
+ require 'nokogiri-xmlsec'
2
+ require 'securerandom'
3
+ require 'time'
4
+
5
+ require 'saml2/assertion'
6
+ require 'saml2/authn_statement'
7
+ require 'saml2/base'
8
+ require 'saml2/subject'
9
+
10
+ module SAML2
11
+ class Response < Base
12
+ module Status
13
+ SUCCESS = "urn:oasis:names:tc:SAML:2.0:status:Success".freeze
14
+ end
15
+
16
+ attr_reader :id, :issue_instant, :assertions
17
+ attr_accessor :issuer, :in_response_to, :destination, :status_code
18
+
19
+ def self.respond_to(authn_request, issuer, name_id, attributes = nil)
20
+ response = initiate(nil, issuer, name_id)
21
+ response.in_response_to = authn_request.id
22
+ response.destination = authn_request.assertion_consumer_service.location
23
+ confirmation = response.assertions.first.subject.confirmation
24
+ confirmation.in_response_to = authn_request.id
25
+ confirmation.recipient = response.destination
26
+ if attributes && authn_request.attribute_consuming_service
27
+ statement = authn_request.attribute_consuming_service.create_statement(attributes)
28
+ response.assertions.first.statements << statement if statement
29
+ end
30
+ response
31
+ end
32
+
33
+ def self.initiate(service_provider, issuer, name_id, attributes = nil)
34
+ response = new
35
+ response.issuer = issuer
36
+ response.destination = service_provider.assertion_consumer_services.default.location if service_provider
37
+ assertion = Assertion.new
38
+ assertion.subject = Subject.new
39
+ assertion.subject.name_id = name_id
40
+ assertion.subject.confirmation = Subject::Confirmation.new
41
+ assertion.subject.confirmation.method = Subject::Confirmation::Methods::BEARER
42
+ assertion.subject.confirmation.not_before = Time.now.utc
43
+ assertion.subject.confirmation.not_on_or_after = Time.now.utc + 30
44
+ assertion.subject.confirmation.recipient = response.destination if response.destination
45
+ assertion.issuer = issuer
46
+ authn_statement = AuthnStatement.new
47
+ authn_statement.authn_instant = response.issue_instant
48
+ authn_statement.authn_context_class_ref = AuthnStatement::Classes::UNSPECIFIED
49
+ assertion.statements << authn_statement
50
+ if attributes && service_provider.attribute_consuming_services.default
51
+ statement = service_provider.attribute_consuming_services.default.create_statement(attributes)
52
+ assertion.statements << statement if statement
53
+ end
54
+ response.assertions << assertion
55
+ response
56
+ end
57
+
58
+ def initialize
59
+ @id = "_#{SecureRandom.uuid}"
60
+ @status_code = Status::SUCCESS
61
+ @issue_instant = Time.now.utc
62
+ @assertions = []
63
+ end
64
+
65
+ def sign(*args)
66
+ assertions.each { |assertion| assertion.sign(*args) }
67
+ end
68
+
69
+ private
70
+ def build(builder)
71
+ builder['samlp'].Response(
72
+ 'xmlns:samlp' => Namespaces::SAMLP,
73
+ ID: id,
74
+ Version: '2.0',
75
+ IssueInstant: issue_instant.iso8601,
76
+ Destination: destination
77
+ ) do |builder|
78
+ builder.parent['InResponseTo'] = in_response_to if in_response_to
79
+
80
+ issuer.build(builder, element: 'Issuer', include_namespace: true) if issuer
81
+
82
+ builder['samlp'].Status do |builder|
83
+ builder['samlp'].StatusCode(Value: status_code)
84
+ end
85
+
86
+ assertions.each do |assertion|
87
+ builder.parent << assertion.to_xml
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
data/lib/saml2/role.rb ADDED
@@ -0,0 +1,53 @@
1
+ require 'set'
2
+
3
+ require 'saml2/base'
4
+ require 'saml2/organization_and_contacts'
5
+ require 'saml2/key'
6
+
7
+ module SAML2
8
+ class Role < Base
9
+ module Protocols
10
+ SAML2 = 'urn:oasis:names:tc:SAML:2.0:protocol'.freeze
11
+ end
12
+
13
+ include OrganizationAndContacts
14
+
15
+ attr_writer :supported_protocols, :keys
16
+
17
+ def initialize(node = nil)
18
+ super
19
+ @root = node
20
+ unless @root
21
+ @supported_protocols = Set.new
22
+ @supported_protocols << Protocols::SAML2
23
+ @keys = []
24
+ end
25
+ end
26
+
27
+ def supported_protocols
28
+ @supported_protocols ||= @root['protocolSupportEnumeration'].split
29
+ end
30
+
31
+ def keys
32
+ @keys ||= load_object_array(@root, 'md:KeyDescriptor', Key)
33
+ end
34
+
35
+ def signing_keys
36
+ keys.select { |key| key.signing? }
37
+ end
38
+
39
+ def encryption_keys
40
+ keys.select { |key| key.encryption? }
41
+ end
42
+
43
+ protected
44
+ # should be called from inside the role element
45
+ def build(builder)
46
+ builder.parent['protocolSupportEnumeration'] = supported_protocols.to_a.join(' ')
47
+ keys.each do |key|
48
+ key.build(builder)
49
+ end
50
+ super
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,18 @@
1
+ module SAML2
2
+ module Schemas
3
+ def self.metadata
4
+ @metadata ||= schema('saml-schema-metadata-2.0.xsd')
5
+ end
6
+
7
+ def self.protocol
8
+ @protocol ||= schema('saml-schema-protocol-2.0.xsd')
9
+ end
10
+
11
+ private
12
+ def self.schema(filename)
13
+ Dir.chdir(File.expand_path(File.join(__FILE__, '../../../schemas'))) do
14
+ Nokogiri::XML::Schema(File.read(filename))
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,30 @@
1
+ require 'nokogiri'
2
+
3
+ require 'saml2/endpoint'
4
+ require 'saml2/sso'
5
+
6
+ module SAML2
7
+ class ServiceProvider < SSO
8
+ class << self
9
+ alias_method :from_xml, :new
10
+ end
11
+
12
+ def initialize(root)
13
+ @root = root
14
+ end
15
+
16
+ def assertion_consumer_services
17
+ @assertion_consumer_services ||= begin
18
+ nodes = @root.xpath('md:AssertionConsumerService', Namespaces::ALL)
19
+ Endpoint::Indexed::Array.from_xml(nodes)
20
+ end
21
+ end
22
+
23
+ def attribute_consuming_services
24
+ @attribute_consuming_services ||= begin
25
+ nodes = @root.xpath('md:AttributeConsumingService', Namespaces::ALL)
26
+ AttributeConsumingService::Array.from_xml(nodes)
27
+ end
28
+ end
29
+ end
30
+ end
data/lib/saml2/sso.rb ADDED
@@ -0,0 +1,36 @@
1
+ require 'saml2/role'
2
+
3
+ module SAML2
4
+ class SSO < Role
5
+ attr_reader :single_logout_services, :name_id_formats
6
+
7
+ def initialize(node = nil)
8
+ super
9
+ unless node
10
+ @single_logout_services = []
11
+ @name_id_formats = []
12
+ end
13
+ end
14
+
15
+ def single_logout_services
16
+ @single_logout_services ||= load_object_array(@root, 'md:SingleLogoutService', Endpoint)
17
+ end
18
+
19
+ def name_id_formats
20
+ @name_id_formats ||= load_string_array(@root, 'md:NameIDFormat')
21
+ end
22
+
23
+ protected
24
+ # should be called from inside the role element
25
+ def build(builder)
26
+ super
27
+
28
+ single_logout_services.each do |slo|
29
+ slo.build(builder, 'SingleLogoutService')
30
+ end
31
+ name_id_formats.each do |nif|
32
+ builder['md'].NameIDFormat(nif)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,49 @@
1
+ require 'saml2/name_id'
2
+ require 'saml2/namespaces'
3
+
4
+ module SAML2
5
+ class Subject
6
+ attr_accessor :name_id, :confirmation
7
+
8
+ def self.from_xml(node)
9
+ return nil unless node
10
+ subject = new
11
+ subject.name_id = NameID.from_xml(node.at_xpath('saml:NameID', Namespaces::ALL))
12
+
13
+ subject
14
+ end
15
+
16
+ def build(builder)
17
+ builder['saml'].Subject do |builder|
18
+ name_id.build(builder) if name_id
19
+ confirmation.build(builder) if confirmation
20
+ end
21
+ end
22
+
23
+ class Confirmation
24
+ module Methods
25
+ BEARER = 'urn:oasis:names:tc:SAML:2.0:cm:bearer'.freeze
26
+ HOLDER_OF_KEY = 'urn:oasis:names:tc:SAML:2.0:cm:holder-of-key'.freeze
27
+ SENDER_VOUCHES = 'urn:oasis:names:tc:SAML:2.0:cm:sender-vouches'.freeze
28
+ end
29
+
30
+ attr_accessor :method, :not_before, :not_on_or_after, :recipient, :in_response_to
31
+
32
+ def build(builder)
33
+ builder['saml'].SubjectConfirmation('Method' => method) do |builder|
34
+ if in_response_to ||
35
+ recipient ||
36
+ not_before ||
37
+ not_on_or_after
38
+ builder['saml'].SubjectConfirmationData do |builder|
39
+ builder.parent['NotBefore'] = not_before.iso8601 if not_before
40
+ builder.parent['NotOnOrAfter'] = not_on_or_after.iso8601 if not_on_or_after
41
+ builder.parent['Recipient'] = recipient if recipient
42
+ builder.parent['InResponseTo'] = in_response_to if in_response_to
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,3 @@
1
+ module SAML2
2
+ VERSION = '1.0.0'
3
+ end
@@ -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-core-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>