Class: SAML2::AuthnRequest

Inherits:
Request show all
Defined in:
lib/saml2/authn_request.rb

Instance Attribute Summary collapse

Attributes inherited from Message

#destination, #errors, #issuer

Attributes inherited from Base

#xml

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Message

from_xml, #from_xml, #id, #initialize, #issue_instant, parse, #sign, #valid_schema?, #validate

Methods included from Signable

#sign, #signature, #signed?, #signing_key, #valid_signature?, #validate_signature

Methods inherited from Base

#decrypt, from_xml, #from_xml, #initialize, #inspect, load_object_array, load_string_array, lookup_qname, #to_s, #to_xml

Constructor Details

This class inherits a constructor from SAML2::Message

Instance Attribute Details

#assertion_consumer_serviceAssertionConsumerService? (readonly)

Must call #resolve before accessing.

Returns:

  • (AssertionConsumerService, nil)


117
118
119
# File 'lib/saml2/authn_request.rb', line 117

def assertion_consumer_service
  @assertion_consumer_service
end

#assertion_consumer_service_indexInteger?

Returns:

  • (Integer, nil)


123
124
125
126
127
128
# File 'lib/saml2/authn_request.rb', line 123

def assertion_consumer_service_index
  if xml && !instance_variable_defined?(:@assertion_consumer_service_index)
    @assertion_consumer_service_index = xml["AssertionConsumerServiceIndex"]&.to_i
  end
  @assertion_consumer_service_index
end

#assertion_consumer_service_urlString?

Returns:

  • (String, nil)


131
132
133
134
135
136
# File 'lib/saml2/authn_request.rb', line 131

def assertion_consumer_service_url
  if xml && !instance_variable_defined?(:@assertion_consumer_service_url)
    @assertion_consumer_service_url = xml["AssertionConsumerServiceURL"]
  end
  @assertion_consumer_service_url
end

#attribute_consuming_serviceAttributeConsumingService? (readonly)

Must call #resolve before accessing.

Returns:



120
121
122
# File 'lib/saml2/authn_request.rb', line 120

def attribute_consuming_service
  @attribute_consuming_service
end

#attribute_consuming_service_indexInteger?

Returns:

  • (Integer, nil)


139
140
141
142
143
144
# File 'lib/saml2/authn_request.rb', line 139

def attribute_consuming_service_index
  if xml && !instance_variable_defined?(:@attribute_consuming_service_index)
    @attribute_consuming_service_index = xml["AttributeConsumingServiceIndex"]&.to_i
  end
  @attribute_consuming_service_index
end

#force_authn=(value) ⇒ Boolean? (writeonly)

Returns:

  • (Boolean, nil)


24
25
26
# File 'lib/saml2/authn_request.rb', line 24

def force_authn=(value)
  @force_authn = value
end

#name_id_policyNameID::Policy?

Returns:



108
109
110
111
112
113
# File 'lib/saml2/authn_request.rb', line 108

def name_id_policy
  if xml && !instance_variable_defined?(:@name_id_policy)
    @name_id_policy = NameID::Policy.from_xml(xml.at_xpath("samlp:NameIDPolicy", Namespaces::ALL))
  end
  @name_id_policy
end

#passive=(value) ⇒ Boolean? (writeonly)

Returns:

  • (Boolean, nil)


24
25
26
# File 'lib/saml2/authn_request.rb', line 24

def passive=(value)
  @passive = value
end

#protocol_bindingString?

Returns:

  • (String, nil)


159
160
161
162
# File 'lib/saml2/authn_request.rb', line 159

def protocol_binding
  @protocol_binding = xml["ProtocolBinding"] if xml && !instance_variable_defined?(:@protocol_binding)
  @protocol_binding
end

#requested_authn_contextObject



172
173
174
175
176
177
178
# File 'lib/saml2/authn_request.rb', line 172

def requested_authn_context
  if xml && !instance_variable_defined?(:@requested_authn_context)
    @requested_authn_context = RequestedAuthnContext.from_xml(xml.at_xpath("samlp:RequestedAuthnContext",
                                                                           Namespaces::ALL))
  end
  @requested_authn_context
end

Class Method Details

.initiate(issuer, identity_provider = nil, assertion_consumer_service: nil, service_provider: nil, binding: Bindings::HTTPRedirect::URN) ⇒ AuthnRequest

TODO:

go over these params, and use kwargs. Maybe pass Entity instead of ServiceProvider.

Initiate a SAML SSO flow, from a service provider to an identity provider.

Parameters:

  • issuer (NameID)
  • identity_provider (IdentityProvider, nil) (defaults to: nil)
  • assertion_consumer_service (Endpoint::Indexed, nil) (defaults to: nil)
  • service_provider (ServiceProvider, nil) (defaults to: nil)
  • binding (String) (defaults to: Bindings::HTTPRedirect::URN)

    the binding to use for the request

Returns:



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/saml2/authn_request.rb', line 38

def self.initiate(issuer, identity_provider = nil,
                  assertion_consumer_service: nil,
                  service_provider: nil,
                  binding: Bindings::HTTPRedirect::URN)
  authn_request = new
  authn_request.issuer = issuer
  if identity_provider
    authn_request.destination = identity_provider
                                .single_sign_on_services
                                .choose_endpoint(binding)
                                &.location
  end
  authn_request.name_id_policy = NameID::Policy.new(true, NameID::Format::UNSPECIFIED)
  assertion_consumer_service ||= service_provider.assertion_consumer_services.default if service_provider
  if assertion_consumer_service
    authn_request.protocol_binding = assertion_consumer_service.binding
    authn_request.assertion_consumer_service_url = assertion_consumer_service.location
  end
  authn_request
end

Instance Method Details

#build(builder) ⇒ void

This method returns an undefined value.

Serialize this object to XML, as part of a larger document

Parameters:

  • builder (Nokogiri::XML::Builder)

    The builder helper object to serialize to.



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/saml2/authn_request.rb', line 181

def build(builder)
  builder["samlp"].AuthnRequest(
    "xmlns:samlp" => Namespaces::SAMLP,
    "xmlns:saml" => Namespaces::SAML
  ) do |authn_request|
    super(authn_request)

    if assertion_consumer_service_index
      authn_request.parent["AssertionConsumerServiceIndex"] =
        assertion_consumer_service_index
    end
    if assertion_consumer_service_url
      authn_request.parent["AssertionConsumerServiceURL"] =
        assertion_consumer_service_url
    end
    if attribute_consuming_service_index
      authn_request.parent["AttributeConsumingServiceIndex"] =
        attribute_consuming_service_index
    end
    authn_request.parent["ForceAuthn"] = force_authn? unless force_authn?.nil?
    authn_request.parent["IsPassive"] = passive? unless passive?.nil?
    authn_request.parent["ProtocolBinding"] = protocol_binding if protocol_binding

    subject&.build(authn_request)
    name_id_policy&.build(authn_request)
    requested_authn_context&.build(authn_request)
  end
end

#force_authn?true, ...

Returns:

  • (true, false, nil)


147
148
149
150
# File 'lib/saml2/authn_request.rb', line 147

def force_authn?
  @force_authn = xml["ForceAuthn"]&.== "true" if xml && !instance_variable_defined?(:@force_authn)
  @force_authn
end

#passive?true, ...

Returns:

  • (true, false, nil)


153
154
155
156
# File 'lib/saml2/authn_request.rb', line 153

def passive?
  @passive = xml["IsPassive"]&.== "true" if xml && !instance_variable_defined?(:@passive)
  @passive
end

#resolve(service_provider) ⇒ Boolean

Populate #assertion_consumer_service and #attribute_consuming_service attributes.

Given ServiceProvider metadata, resolve the index/urls in this object to actual objects.

Parameters:

Returns:

  • (Boolean)


87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/saml2/authn_request.rb', line 87

def resolve(service_provider)
  # TODO: check signature if present

  @assertion_consumer_service =
    if assertion_consumer_service_url
      service_provider.assertion_consumer_services.find do |acs|
        acs.location == assertion_consumer_service_url
      end
    else
      service_provider.assertion_consumer_services.resolve(assertion_consumer_service_index)
    end
  @attribute_consuming_service =
    service_provider.attribute_consuming_services.resolve(attribute_consuming_service_index)

  return false unless @assertion_consumer_service
  return false if attribute_consuming_service_index && !@attribute_consuming_service

  true
end

#subjectSubject?

Returns:



165
166
167
168
169
170
# File 'lib/saml2/authn_request.rb', line 165

def subject
  if xml && !instance_variable_defined?(:@subject)
    @subject = Subject.from_xml(xml.at_xpath("saml:Subject", Namespaces::ALL))
  end
  @subject
end

#valid_interoperable_profile?Boolean



68
69
70
71
72
73
74
75
76
77
# File 'lib/saml2/authn_request.rb', line 68

def valid_interoperable_profile?
  # It's a subset of Web Browser SSO profile
  return false unless valid_web_browser_sso_profile?

  return false unless assertion_consumer_service_url
  return false if protocol_binding && protocol_binding != Bindings::HTTP_POST::URN
  return false if subject

  true
end

#valid_web_browser_sso_profile?Boolean

Returns:

  • (Boolean)

See Also:



60
61
62
63
64
65
# File 'lib/saml2/authn_request.rb', line 60

def valid_web_browser_sso_profile?
  return false unless issuer
  return false if issuer.format && issuer.format != NameID::Format::ENTITY

  true
end