class SAML2::AuthnRequest

Attributes

assertion_consumer_service[R]

Must call {#resolve} before accessing. @return [AssertionConsumerService, nil]

assertion_consumer_service_index[W]
assertion_consumer_service_url[W]
attribute_consuming_service[R]

Must call {#resolve} before accessing. @return [AttributeConsumingService, nil]

attribute_consuming_service_index[W]
force_authn[W]

@return [Boolean, nil]

name_id_policy[W]
passive[W]

@return [Boolean, nil]

protocol_binding[W]
requested_authn_context[RW]

@return [RequestedAuthnContext, nil]

Public Class Methods

initiate(issuer, identity_provider = nil, assertion_consumer_service: nil, service_provider: nil) click to toggle source

Initiate a SAML SSO flow, from a service provider to an identity provider. @todo go over these params, and use kwargs. Maybe pass Entity instead

of ServiceProvider.

@param issuer [NameID] @param identity_provider [IdentityProvider] @param assertion_consumer_service [Endpoint::Indexed] @param service_provider [ServiceProvider] @return [AuthnRequest]

# File lib/saml2/authn_request.rb, line 37
def self.initiate(issuer, identity_provider = nil,
                  assertion_consumer_service: nil,
                  service_provider: nil)
  authn_request = new
  authn_request.issuer = issuer
  authn_request.destination = identity_provider.single_sign_on_services.first.location if identity_provider
  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

Public Instance Methods

assertion_consumer_service_index() click to toggle source

@return [Integer, nil]

# File lib/saml2/authn_request.rb, line 116
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_url() click to toggle source

@return [String, nil]

# File lib/saml2/authn_request.rb, line 124
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_service_index() click to toggle source

@return [Integer, nil]

# File lib/saml2/authn_request.rb, line 132
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
build(builder) click to toggle source

(see Base#build)

Calls superclass method
# File lib/saml2/authn_request.rb, line 166
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?() click to toggle source

@return [true, false, nil]

# File lib/saml2/authn_request.rb, line 140
def force_authn?
  @force_authn = xml["ForceAuthn"]&.== "true" if xml && !instance_variable_defined?(:@force_authn)
  @force_authn
end
name_id_policy() click to toggle source

@return [NameID::Policy, nil]

# File lib/saml2/authn_request.rb, line 101
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?() click to toggle source

@return [true, false, nil]

# File lib/saml2/authn_request.rb, line 146
def passive?
  @passive = xml["IsPassive"]&.== "true" if xml && !instance_variable_defined?(:@passive)
  @passive
end
protocol_binding() click to toggle source

@return [String, nil]

# File lib/saml2/authn_request.rb, line 152
def protocol_binding
  @protocol_binding = xml["ProtocolBinding"] if xml && !instance_variable_defined?(:@protocol_binding)
  @protocol_binding
end
resolve(service_provider) click to toggle source

Populate {#assertion_consumer_service} and {#attribute_consuming_service} attributes.

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

@param service_provider [ServiceProvider] @return [Boolean]

# File lib/saml2/authn_request.rb, line 80
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
subject() click to toggle source

@return [Subject, nil]

# File lib/saml2/authn_request.rb, line 158
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?() click to toggle source

@see saml2int.org/profile/current/#section82

# File lib/saml2/authn_request.rb, line 61
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?() click to toggle source

@see docs.oasis-open.org/security/saml/v2.0/saml-profiles-2.0-os.pdf section 4.1

# File lib/saml2/authn_request.rb, line 53
def valid_web_browser_sso_profile?
  return false unless issuer
  return false if issuer.format && issuer.format != NameID::Format::ENTITY

  true
end