generate saml authnrequests with saml2 gem
closes CNVS-36682 note that the old way of doing it is still there, controlled by a hidden account level setting test plan: * smoke test a SAML login Change-Id: I24c8c6ee472b90e274ec93d09cc6f58d03ed77f5 Reviewed-on: https://gerrit.instructure.com/130136 Reviewed-by: Rob Orton <rob@instructure.com> QA-Review: Jeremy Putnam <jeremyp@instructure.com> Tested-by: Jenkins Product-Review: Cody Cutrer <cody@instructure.com>
This commit is contained in:
parent
5f54decbce
commit
d2ea1fb2a9
|
@ -97,7 +97,7 @@ gem 'rotp', '3.3.0', require: false
|
|||
gem 'net-ldap', '0.16.0', require: false
|
||||
gem 'ruby-duration', '3.2.3', require: false
|
||||
gem 'ruby-saml-mod', '0.3.7'
|
||||
gem 'saml2', '1.1.3', require: false
|
||||
gem 'saml2', '1.1.5', require: false
|
||||
gem 'nokogiri-xmlsec-me-harder', '0.9.3pre', require: false, github: 'instructure/nokogiri-xmlsec-me-harder', ref: '57d071040cc4649db9f158e09bbcea028271a4a6'
|
||||
gem 'rubycas-client', '2.3.9', require: false
|
||||
gem 'rubyzip', '1.2.0', require: 'zip'
|
||||
|
|
|
@ -26,7 +26,9 @@ class Login::SamlController < ApplicationController
|
|||
before_action :fix_ms_office_redirects, only: :new
|
||||
|
||||
def new
|
||||
auth_redirect(aac)
|
||||
increment_saml_stat("login_attempt")
|
||||
redirect_to delegated_auth_redirect_uri(aac.generate_authn_request_redirect(host: request.host_with_port,
|
||||
parent_registration: session[:parent_registration]))
|
||||
end
|
||||
|
||||
def create
|
||||
|
@ -324,7 +326,10 @@ class Login::SamlController < ApplicationController
|
|||
|
||||
|
||||
def observee_validation
|
||||
auth_redirect(@domain_root_account.parent_registration_aac)
|
||||
increment_saml_stat("login_attempt")
|
||||
redirect_to delegated_auth_redirect_uri(
|
||||
@domain_root_account.parent_registration_aac.generate_authn_request_redirect(host: request.host_with_port,
|
||||
parent_registration: session[:parent_registration]))
|
||||
end
|
||||
|
||||
protected
|
||||
|
@ -340,21 +345,6 @@ class Login::SamlController < ApplicationController
|
|||
CanvasStatsd::Statsd.increment("saml.#{CanvasStatsd::Statsd.escape(request.host)}.#{key}")
|
||||
end
|
||||
|
||||
def auth_redirect(aac)
|
||||
increment_saml_stat("login_attempt")
|
||||
settings = aac.saml_settings(request.host_with_port)
|
||||
request = Onelogin::Saml::AuthRequest.new(settings)
|
||||
forward_url = request.generate_request
|
||||
if aac.debugging? && !aac.debug_get(:request_id)
|
||||
aac.debug_set(:request_id, request.id)
|
||||
aac.debug_set(:to_idp_url, forward_url)
|
||||
aac.debug_set(:to_idp_xml, request.request_xml)
|
||||
aac.debug_set(:debugging, "Forwarding user to IdP for authentication")
|
||||
end
|
||||
forward_url << '&ForceAuthn=true' if session[:parent_registration]
|
||||
redirect_to delegated_auth_redirect_uri(forward_url)
|
||||
end
|
||||
|
||||
def complete_observee_addition(registration_data)
|
||||
observee_unique_id = registration_data[:observee][:unique_id]
|
||||
observee = @domain_root_account.pseudonyms.by_unique_id(observee_unique_id).first.user
|
||||
|
|
|
@ -196,9 +196,11 @@ class AccountAuthorizationConfig::SAML < AccountAuthorizationConfig::Delegated
|
|||
entity.entity_id = idp_entity_id
|
||||
|
||||
idp = SAML2::IdentityProvider.new
|
||||
idp.single_sign_on_services << SAML2::Endpoint.new(log_in_url,
|
||||
SAML2::Bindings::HTTPRedirect::URN)
|
||||
if log_out_url.present?
|
||||
idp.single_logout_services << SAML2::Endpoint.new(log_out_url,
|
||||
SAML2::Endpoint::Bindings::HTTP_REDIRECT)
|
||||
SAML2::Bindings::HTTPRedirect::URN)
|
||||
end
|
||||
entity.roles << idp
|
||||
entity
|
||||
|
@ -218,7 +220,7 @@ class AccountAuthorizationConfig::SAML < AccountAuthorizationConfig::Delegated
|
|||
|
||||
sp = SAML2::ServiceProvider.new
|
||||
sp.single_logout_services << SAML2::Endpoint.new("#{HostUrl.protocol}://#{hosts.first}/login/saml/logout",
|
||||
SAML2::Endpoint::Bindings::HTTP_REDIRECT)
|
||||
SAML2::Bindings::HTTPRedirect::URN)
|
||||
|
||||
hosts.each_with_index do |host, i|
|
||||
sp.assertion_consumer_services << SAML2::Endpoint::Indexed.new("#{HostUrl.protocol}://#{host}/login/saml",
|
||||
|
@ -240,6 +242,42 @@ class AccountAuthorizationConfig::SAML < AccountAuthorizationConfig::Delegated
|
|||
entity
|
||||
end
|
||||
|
||||
def generate_authn_request_redirect(host: nil, parent_registration: false)
|
||||
if account.settings[:use_legacy_saml_authn_request]
|
||||
settings = saml_settings(host)
|
||||
request = Onelogin::Saml::AuthRequest.new(settings)
|
||||
forward_url = request.generate_request
|
||||
if debugging? && !debug_get(:request_id)
|
||||
debug_set(:request_id, request.id)
|
||||
debug_set(:to_idp_url, forward_url)
|
||||
debug_set(:to_idp_xml, request.request_xml)
|
||||
debug_set(:debugging, "Forwarding user to IdP for authentication")
|
||||
end
|
||||
forward_url << '&ForceAuthn=true' if parent_registration
|
||||
else
|
||||
sp_metadata = self.class.sp_metadata_for_account(account, host).service_providers.first
|
||||
authn_request = SAML2::AuthnRequest.initiate(SAML2::NameID.new(entity_id),
|
||||
idp_metadata.identity_providers.first,
|
||||
service_provider: sp_metadata)
|
||||
authn_request.name_id_policy.format = identifier_format if identifier_format.present?
|
||||
if requested_authn_context.present?
|
||||
authn_request.requested_authn_context = RequestedAuthnContext.new
|
||||
authn_request.requested_authn_context.class_ref = requested_authn_context
|
||||
authn_request.requested_authn_context.comparison = :exact
|
||||
end
|
||||
authn_request.force_authn = true if parent_registration
|
||||
forward_url = SAML2::Bindings::HTTPRedirect.encode(authn_request)
|
||||
|
||||
if debugging? && !debug_get(:request_id)
|
||||
debug_set(:request_id, authn_request.id)
|
||||
debug_set(:to_idp_url, forward_url)
|
||||
debug_set(:to_idp_xml, authn_request.to_s)
|
||||
debug_set(:debugging, "Forwarding user to IdP for authentication")
|
||||
end
|
||||
end
|
||||
forward_url
|
||||
end
|
||||
|
||||
def self.sp_metadata_for_account(account, current_host = nil)
|
||||
sp_metadata(saml_default_entity_id_for_account(account),HostUrl.context_hosts(account, current_host))
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue