class OmniAuth::Strategies::Suomifi
Public Class Methods
# File lib/omniauth/strategies/suomifi.rb, line 491 def initialize(app, *args, &block) super # Add the request attributes to the options. options[:request_attributes] = scoped_request_attributes options[:sp_name_qualifier] = options[:sp_entity_id] if options[:sp_name_qualifier].nil? # Remove the nil options from the origianl options array that will be # defined by the Suomi.fi options %i[ certificate private_key idp_name_qualifier name_identifier_format security ].each do |key| options.delete(key) if options[key].nil? end # Add the Suomi.fi options to the local options, most of which are # fetched from the metadata. The options array is the one that gets # priority in case it overrides some of the metadata or locally defined # option values. @options = OmniAuth::Strategy::Options.new( suomifi_options.merge(options) ) end
Public Instance Methods
Override the callback URL so that it always matches the one expected by Suomi.fi. No additional query string parameters can be included in the string.
# File lib/omniauth/strategies/suomifi.rb, line 551 def callback_url full_host + script_name + callback_path end
Override the request phase to be able to pass the locale parameter to the redirect URL. Note that this needs to be the last parameter to be passed to the redirect URL.
# File lib/omniauth/strategies/suomifi.rb, line 522 def request_phase authn_request = OneLogin::RubySaml::Authrequest.new locale = locale_for_authn_request with_settings do |settings| url = authn_request.create(settings, additional_params_for_authn_request) url += "&locale=#{CGI.escape(locale)}" unless locale.nil? redirect(url) end end
This method can be used externally to fetch information about the response, e.g. in case of failures.
# File lib/omniauth/strategies/suomifi.rb, line 535 def response_object return nil unless request.params['SAMLResponse'] with_settings do |settings| response = OneLogin::RubySaml::Response.new( request.params['SAMLResponse'], options_for_response_object.merge(settings: settings) ) response.attributes['fingerprint'] = settings.idp_cert_fingerprint response end end
Private Instance Methods
# File lib/omniauth/strategies/suomifi.rb, line 600 def certificate File.read(options.certificate_file) if options.certificate_file end
# File lib/omniauth/strategies/suomifi.rb, line 608 def idp_metadata_url case options.mode when :test 'https://testi.apro.tunnistus.fi/static/metadata/idp-metadata.xml' else # :production 'https://tunnistus.suomi.fi/static/metadata/idp-metadata-tunnistautuminen.xml' end end
# File lib/omniauth/strategies/suomifi.rb, line 674 def locale_for_authn_request if options.idp_sso_service_url_locale_params.is_a?(Array) options.idp_sso_service_url_locale_params.each do |param| next unless request.params.key?(param.to_s) locale = parse_language_value(request.params[param.to_s]) return locale unless locale.nil? end end options.idp_sso_service_url_default_locale end
Suomi.fi requires that the service provider needs to end the local user session BEFORE sending the logout request to the identity provider.
# File lib/omniauth/strategies/suomifi.rb, line 559 def other_phase_for_spslo return super unless options.idp_slo_service_url with_settings do |settings| # Some session variables are needed when generating the logout request request = generate_logout_request(settings) # Destroy the local user session options[:idp_slo_session_destroy].call @env, session # Send the logout request to the identity provider redirect(request) end end
# File lib/omniauth/strategies/suomifi.rb, line 687 def parse_language_value(string) language = string.sub('_', '-').split('-').first language if language =~ /^(fi|sv|en)$/ end
# File lib/omniauth/strategies/suomifi.rb, line 604 def private_key File.read(options.private_key_file) if options.private_key_file end
# File lib/omniauth/strategies/suomifi.rb, line 666 def saml_attributes {}.tap do |attrs| options.saml_attributes_map.each do |target, source| attrs[target] = find_attribute_by(source) end end end
# File lib/omniauth/strategies/suomifi.rb, line 585 def scoped_request_attributes scopes = [:limited] scopes << :medium_extensive if options.scope_of_data == :medium_extensive scopes << :medium_extensive if options.scope_of_data == :extensive scopes << :extensive if options.scope_of_data == :extensive names = options.scoped_attributes.select do |key, _v| scopes.include?(key.to_sym) end.values.flatten options.possible_request_attributes.select do |attr| names.include?(attr[:name]) end end
This will return true if the VTJ search (population information system, väestötietojärjestelmä) was successful and information about the person was transmitted in the SAML response.
# File lib/omniauth/strategies/suomifi.rb, line 661 def search_success success_string = find_attribute_by(['urn:oid:1.2.246.517.3002.111.2']) success_string == 'true' end
Overridden to disable passing the relay state with a request parameter which is possible in the default implementation.
# File lib/omniauth/strategies/suomifi.rb, line 574 def slo_relay_state state = super # Ensure that we are only using the relay states to redirect the user # within the current website. This forces the relay state to always # start with a single forward slash character (/). return '/' unless state =~ %r{^/[^/].*} state end
# File lib/omniauth/strategies/suomifi.rb, line 617 def suomifi_options idp_metadata_parser = OneLogin::RubySaml::IdpMetadataParser.new # Returns OneLogin::RubySaml::Settings prepopulated with idp metadata # We are using the redirect binding for the SSO and SLO URLs as these # are the ones expected by omniauth-saml. Otherwise the default would be # the first one defined in the IdP metadata, which would be the # HTTP-POST binding. settings = idp_metadata_parser.parse_remote_to_hash( idp_metadata_url, true, sso_binding: ['urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'], slo_binding: ['urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'] ) if settings[:idp_slo_response_service_url].nil? && settings[:idp_slo_target_url].nil? # Mitigation after ruby-saml update to 1.12.x. This gem has been # originally developed relying on the `:idp_slo_target_url` settings # which was removed from the newer versions. The SLO requests won't # work unless `:idp_slo_response_service_url` is defined in the # metadata through the `ResponseLocation` attribute in the # `<SingleLogoutService />` node. settings[:idp_slo_target_url] ||= settings[:idp_slo_service_url] end # Local certificate and private key to decrypt the responses settings[:certificate] = certificate settings[:private_key] = private_key # Define the security settings as there are some defaults that need to be # modified security_defaults = OneLogin::RubySaml::Settings::DEFAULTS[:security] settings[:security] = security_defaults.merge(options.security_settings) # Add some extra information that is necessary for correctly formatted # logout requests. settings[:idp_name_qualifier] = settings[:idp_entity_id] settings end