sso_login_box_for_ntu/ruby-saml-custom/lib/onelogin/ruby-saml/settings.rb

286 lines
9.7 KiB
Ruby

require "xml_security"
require "onelogin/ruby-saml/attribute_service"
require "onelogin/ruby-saml/utils"
require "onelogin/ruby-saml/validation_error"
# Only supports SAML 2.0
module OneLogin
module RubySaml
# SAML2 Toolkit Settings
#
class Settings
def initialize(overrides = {}, keep_security_attributes = false)
if keep_security_attributes
security_attributes = overrides.delete(:security) || {}
config = DEFAULTS.merge(overrides)
config[:security] = DEFAULTS[:security].merge(security_attributes)
else
config = DEFAULTS.merge(overrides)
end
config.each do |k,v|
acc = "#{k}=".to_sym
if respond_to? acc
value = v.is_a?(Hash) ? v.dup : v
send(acc, value)
end
end
@attribute_consuming_service = AttributeService.new
end
# IdP Data
attr_accessor :idp_entity_id
attr_writer :idp_sso_service_url
attr_writer :idp_slo_service_url
attr_accessor :idp_slo_response_service_url
attr_accessor :idp_cert
attr_accessor :idp_cert_fingerprint
attr_accessor :idp_cert_fingerprint_algorithm
attr_accessor :idp_cert_multi
attr_accessor :idp_attribute_names
attr_accessor :idp_name_qualifier
attr_accessor :valid_until
# SP Data
attr_writer :sp_entity_id
attr_accessor :assertion_consumer_service_url
attr_reader :assertion_consumer_service_binding
attr_writer :single_logout_service_url
attr_accessor :sp_name_qualifier
attr_accessor :name_identifier_format
attr_accessor :name_identifier_value
attr_accessor :name_identifier_value_requested
attr_accessor :sessionindex
attr_accessor :compress_request
attr_accessor :compress_response
attr_accessor :double_quote_xml_attribute_values
attr_accessor :message_max_bytesize
attr_accessor :passive
attr_reader :protocol_binding
attr_accessor :attributes_index
attr_accessor :force_authn
attr_accessor :certificate
attr_accessor :certificate_new
attr_accessor :private_key
attr_accessor :authn_context
attr_accessor :authn_context_comparison
attr_accessor :authn_context_decl_ref
attr_reader :attribute_consuming_service
# Work-flow
attr_accessor :security
attr_accessor :soft
# Deprecated
attr_accessor :assertion_consumer_logout_service_url
attr_reader :assertion_consumer_logout_service_binding
attr_accessor :issuer
attr_accessor :idp_sso_target_url
attr_accessor :idp_slo_target_url
# @return [String] IdP Single Sign On Service URL
#
def idp_sso_service_url
@idp_sso_service_url || @idp_sso_target_url
end
# @return [String] IdP Single Logout Service URL
#
def idp_slo_service_url
@idp_slo_service_url || @idp_slo_target_url
end
# @return [String] IdP Single Sign On Service Binding
#
def idp_sso_service_binding
@idp_sso_service_binding || idp_binding_from_embed_sign
end
# Setter for IdP Single Sign On Service Binding
# @param value [String, Symbol].
#
def idp_sso_service_binding=(value)
@idp_sso_service_binding = get_binding(value)
end
# @return [String] IdP Single Logout Service Binding
#
def idp_slo_service_binding
@idp_slo_service_binding || idp_binding_from_embed_sign
end
# Setter for IdP Single Logout Service Binding
# @param value [String, Symbol].
#
def idp_slo_service_binding=(value)
@idp_slo_service_binding = get_binding(value)
end
# @return [String] SP Entity ID
#
def sp_entity_id
@sp_entity_id || @issuer
end
# Setter for SP Protocol Binding
# @param value [String, Symbol].
#
def protocol_binding=(value)
@protocol_binding = get_binding(value)
end
# Setter for SP Assertion Consumer Service Binding
# @param value [String, Symbol].
#
def assertion_consumer_service_binding=(value)
@assertion_consumer_service_binding = get_binding(value)
end
# @return [String] Single Logout Service URL.
#
def single_logout_service_url
@single_logout_service_url || @assertion_consumer_logout_service_url
end
# @return [String] Single Logout Service Binding.
#
def single_logout_service_binding
@single_logout_service_binding || @assertion_consumer_logout_service_binding
end
# Setter for Single Logout Service Binding.
#
# (Currently we only support "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect")
# @param value [String, Symbol]
#
def single_logout_service_binding=(value)
@single_logout_service_binding = get_binding(value)
end
# @deprecated Setter for legacy Single Logout Service Binding parameter.
#
# (Currently we only support "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect")
# @param value [String, Symbol]
#
def assertion_consumer_logout_service_binding=(value)
@assertion_consumer_logout_service_binding = get_binding(value)
end
# Calculates the fingerprint of the IdP x509 certificate.
# @return [String] The fingerprint
#
def get_fingerprint
idp_cert_fingerprint || begin
idp_cert = get_idp_cert
if idp_cert
fingerprint_alg = XMLSecurity::BaseDocument.new.algorithm(idp_cert_fingerprint_algorithm).new
fingerprint_alg.hexdigest(idp_cert.to_der).upcase.scan(/../).join(":")
end
end
end
# @return [OpenSSL::X509::Certificate|nil] Build the IdP certificate from the settings (previously format it)
#
def get_idp_cert
return nil if idp_cert.nil? || idp_cert.empty?
formatted_cert = OneLogin::RubySaml::Utils.format_cert(idp_cert)
OpenSSL::X509::Certificate.new(formatted_cert)
end
# @return [Hash with 2 arrays of OpenSSL::X509::Certificate] Build multiple IdP certificates from the settings.
#
def get_idp_cert_multi
return nil if idp_cert_multi.nil? || idp_cert_multi.empty?
raise ArgumentError.new("Invalid value for idp_cert_multi") if not idp_cert_multi.is_a?(Hash)
certs = {:signing => [], :encryption => [] }
[:signing, :encryption].each do |type|
certs_for_type = idp_cert_multi[type] || idp_cert_multi[type.to_s]
next if !certs_for_type || certs_for_type.empty?
certs_for_type.each do |idp_cert|
formatted_cert = OneLogin::RubySaml::Utils.format_cert(idp_cert)
certs[type].push(OpenSSL::X509::Certificate.new(formatted_cert))
end
end
certs
end
# @return [OpenSSL::X509::Certificate|nil] Build the SP certificate from the settings (previously format it)
#
def get_sp_cert
return nil if certificate.nil? || certificate.empty?
formatted_cert = OneLogin::RubySaml::Utils.format_cert(certificate)
cert = OpenSSL::X509::Certificate.new(formatted_cert)
if security[:check_sp_cert_expiration]
if OneLogin::RubySaml::Utils.is_cert_expired(cert)
raise OneLogin::RubySaml::ValidationError.new("The SP certificate expired.")
end
end
cert
end
# @return [OpenSSL::X509::Certificate|nil] Build the New SP certificate from the settings (previously format it)
#
def get_sp_cert_new
return nil if certificate_new.nil? || certificate_new.empty?
formatted_cert = OneLogin::RubySaml::Utils.format_cert(certificate_new)
OpenSSL::X509::Certificate.new(formatted_cert)
end
# @return [OpenSSL::PKey::RSA] Build the SP private from the settings (previously format it)
#
def get_sp_key
return nil if private_key.nil? || private_key.empty?
formatted_private_key = OneLogin::RubySaml::Utils.format_private_key(private_key)
OpenSSL::PKey::RSA.new(formatted_private_key)
end
def idp_binding_from_embed_sign
security[:embed_sign] ? Utils::BINDINGS[:post] : Utils::BINDINGS[:redirect]
end
def get_binding(value)
return unless value
Utils::BINDINGS[value.to_sym] || value
end
DEFAULTS = {
:assertion_consumer_service_binding => Utils::BINDINGS[:post],
:single_logout_service_binding => Utils::BINDINGS[:redirect],
:idp_cert_fingerprint_algorithm => XMLSecurity::Document::SHA1,
:compress_request => true,
:compress_response => true,
:message_max_bytesize => 250000,
:soft => true,
:double_quote_xml_attribute_values => false,
:security => {
:authn_requests_signed => false,
:logout_requests_signed => false,
:logout_responses_signed => false,
:want_assertions_signed => false,
:want_assertions_encrypted => false,
:want_name_id => false,
:metadata_signed => false,
:embed_sign => false, # Deprecated
:digest_method => XMLSecurity::Document::SHA1,
:signature_method => XMLSecurity::Document::RSA_SHA1,
:check_idp_cert_expiration => false,
:check_sp_cert_expiration => false,
:strict_audience_validation => false,
:lowercase_url_encoding => false
}.freeze
}.freeze
end
end
end