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.
- checksums.yaml +7 -0
- data/Rakefile +13 -0
- data/app/views/saml2/http_post.html.erb +14 -0
- data/lib/saml2.rb +9 -0
- data/lib/saml2/assertion.rb +37 -0
- data/lib/saml2/attribute.rb +127 -0
- data/lib/saml2/attribute/x500.rb +79 -0
- data/lib/saml2/attribute_consuming_service.rb +76 -0
- data/lib/saml2/authn_request.rb +116 -0
- data/lib/saml2/authn_statement.rb +26 -0
- data/lib/saml2/base.rb +53 -0
- data/lib/saml2/contact.rb +50 -0
- data/lib/saml2/endpoint.rb +46 -0
- data/lib/saml2/engine.rb +4 -0
- data/lib/saml2/entity.rb +84 -0
- data/lib/saml2/identity_provider.rb +57 -0
- data/lib/saml2/indexed_object.rb +59 -0
- data/lib/saml2/key.rb +46 -0
- data/lib/saml2/name_id.rb +60 -0
- data/lib/saml2/namespaces.rb +21 -0
- data/lib/saml2/organization.rb +74 -0
- data/lib/saml2/organization_and_contacts.rb +35 -0
- data/lib/saml2/profiles.rb +7 -0
- data/lib/saml2/response.rb +92 -0
- data/lib/saml2/role.rb +53 -0
- data/lib/saml2/schemas.rb +18 -0
- data/lib/saml2/service_provider.rb +30 -0
- data/lib/saml2/sso.rb +36 -0
- data/lib/saml2/subject.rb +49 -0
- data/lib/saml2/version.rb +3 -0
- data/schemas/saml-schema-assertion-2.0.xsd +283 -0
- data/schemas/saml-schema-metadata-2.0.xsd +339 -0
- data/schemas/saml-schema-protocol-2.0.xsd +302 -0
- data/schemas/xenc-schema.xsd +136 -0
- data/schemas/xml.xsd +287 -0
- data/schemas/xmldsig-core-schema.xsd +309 -0
- data/spec/fixtures/authnrequest.xml +12 -0
- data/spec/fixtures/calculated.txt +1 -0
- data/spec/fixtures/certificate.pem +25 -0
- data/spec/fixtures/entities.xml +13 -0
- data/spec/fixtures/privatekey.key +27 -0
- data/spec/fixtures/response_signed.xml +47 -0
- data/spec/fixtures/response_with_attribute_signed.xml +47 -0
- data/spec/fixtures/service_provider.xml +79 -0
- data/spec/fixtures/xmlsec.txt +1 -0
- data/spec/lib/attribute_consuming_service_spec.rb +74 -0
- data/spec/lib/attribute_spec.rb +39 -0
- data/spec/lib/authn_request_spec.rb +52 -0
- data/spec/lib/entity_spec.rb +45 -0
- data/spec/lib/identity_provider_spec.rb +23 -0
- data/spec/lib/indexed_object_spec.rb +38 -0
- data/spec/lib/response_spec.rb +60 -0
- data/spec/lib/service_provider_spec.rb +30 -0
- data/spec/spec_helper.rb +6 -0
- 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,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,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>
|