class OneLogin::RubySaml::Authrequest
SAML2 Authentication. AuthNRequest (SSO SP initiated, Builder)
Attributes
AuthNRequest ID
Public Class Methods
Initializes the AuthNRequest. An Authrequest Object that is an extension of the SamlMessage class. Asigns an ID, a random uuid.
# File lib/onelogin/ruby-saml/authrequest.rb, line 22 def initialize @uuid = OneLogin::RubySaml::Utils.uuid end
Public Instance Methods
Creates the AuthNRequest string. @param settings [OneLogin::RubySaml::Settings|nil] Toolkit settings @param params [Hash] Some extra parameters to be added in the GET for example the RelayState @return [String] AuthNRequest string that includes the SAMLRequest
# File lib/onelogin/ruby-saml/authrequest.rb, line 31 def create(settings, params = {}) params = create_params(settings, params) params_prefix = (settings.idp_sso_target_url =~ /\?/) ? '&' : '?' saml_request = CGI.escape(params.delete("SAMLRequest")) request_params = "#{params_prefix}SAMLRequest=#{saml_request}" params.each_pair do |key, value| request_params << "&#{key.to_s}=#{CGI.escape(value.to_s)}" end raise "Invalid settings, idp_sso_target_url is not set!" if settings.idp_sso_target_url.nil? @login_url = settings.idp_sso_target_url + request_params end
Creates the SAMLRequest String. @param settings [OneLogin::RubySaml::Settings|nil] Toolkit settings @return [String] The SAMLRequest String.
# File lib/onelogin/ruby-saml/authrequest.rb, line 95 def create_authentication_xml_doc(settings) document = create_xml_document(settings) sign_document(document, settings) end
Creates the Get parameters for the request. @param settings [OneLogin::RubySaml::Settings|nil] Toolkit settings @param params [Hash] Some extra parameters to be added in the GET for example the RelayState @return [Hash] Parameters
# File lib/onelogin/ruby-saml/authrequest.rb, line 48 def create_params(settings, params={}) # The method expects :RelayState but sometimes we get 'RelayState' instead. # Based on the HashWithIndifferentAccess value in Rails we could experience # conflicts so this line will solve them. relay_state = params[:RelayState] || params['RelayState'] if relay_state.nil? params.delete(:RelayState) params.delete('RelayState') end request_doc = create_authentication_xml_doc(settings) request_doc.context[:attribute_quote] = :quote if settings.double_quote_xml_attribute_values request = "" request_doc.write(request) Logging.debug "Created AuthnRequest: #{request}" request = deflate(request) if settings.compress_request base64_request = encode(request) request_params = {"SAMLRequest" => base64_request} if settings.security[:authn_requests_signed] && !settings.security[:embed_sign] && settings.private_key params['SigAlg'] = settings.security[:signature_method] url_string = OneLogin::RubySaml::Utils.build_query( :type => 'SAMLRequest', :data => base64_request, :relay_state => relay_state, :sig_alg => params['SigAlg'] ) sign_algorithm = XMLSecurity::BaseDocument.new.algorithm(settings.security[:signature_method]) signature = settings.get_sp_key.sign(sign_algorithm.new, url_string) params['Signature'] = encode(signature) end params.each_pair do |key, value| request_params[key] = value.to_s end request_params end
# File lib/onelogin/ruby-saml/authrequest.rb, line 100 def create_xml_document(settings) time = Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ") request_doc = XMLSecurity::Document.new request_doc.uuid = uuid root = request_doc.add_element "samlp:AuthnRequest", { "xmlns:samlp" => "urn:oasis:names:tc:SAML:2.0:protocol", "xmlns:saml" => "urn:oasis:names:tc:SAML:2.0:assertion" } root.attributes['ID'] = uuid root.attributes['IssueInstant'] = time root.attributes['Version'] = "2.0" root.attributes['Destination'] = settings.idp_sso_target_url unless settings.idp_sso_target_url.nil? root.attributes['IsPassive'] = settings.passive unless settings.passive.nil? root.attributes['ProtocolBinding'] = settings.protocol_binding unless settings.protocol_binding.nil? root.attributes["AttributeConsumingServiceIndex"] = settings.attributes_index unless settings.attributes_index.nil? root.attributes['ForceAuthn'] = settings.force_authn unless settings.force_authn.nil? # Conditionally defined elements based on settings if settings.assertion_consumer_service_url != nil root.attributes["AssertionConsumerServiceURL"] = settings.assertion_consumer_service_url end if settings.issuer != nil issuer = root.add_element "saml:Issuer" issuer.text = settings.issuer end if settings.name_identifier_format != nil root.add_element "samlp:NameIDPolicy", { # Might want to make AllowCreate a setting? "AllowCreate" => "true", "Format" => settings.name_identifier_format } end if settings.authn_context || settings.authn_context_decl_ref if settings.authn_context_comparison != nil comparison = settings.authn_context_comparison else comparison = 'exact' end requested_context = root.add_element "samlp:RequestedAuthnContext", { "Comparison" => comparison, } if settings.authn_context != nil authn_contexts_class_ref = settings.authn_context.is_a?(Array) ? settings.authn_context : [settings.authn_context] authn_contexts_class_ref.each do |authn_context_class_ref| class_ref = requested_context.add_element "saml:AuthnContextClassRef" class_ref.text = authn_context_class_ref end end if settings.authn_context_decl_ref != nil authn_contexts_decl_refs = settings.authn_context_decl_ref.is_a?(Array) ? settings.authn_context_decl_ref : [settings.authn_context_decl_ref] authn_contexts_decl_refs.each do |authn_context_decl_ref| decl_ref = requested_context.add_element "saml:AuthnContextDeclRef" decl_ref.text = authn_context_decl_ref end end end request_doc end
# File lib/onelogin/ruby-saml/authrequest.rb, line 164 def sign_document(document, settings) # embed signature if settings.security[:authn_requests_signed] && settings.private_key && settings.certificate && settings.security[:embed_sign] private_key = settings.get_sp_key cert = settings.get_sp_cert document.sign_document(private_key, cert, settings.security[:signature_method], settings.security[:digest_method]) end document end