From bb8d0b96f9914a9d2585a465ef00c08d37eb420e Mon Sep 17 00:00:00 2001 From: Jonathan Hooper Date: Wed, 28 Feb 2024 11:55:39 -0500 Subject: [PATCH 1/2] LG-12196 Add support for VTR param to the SAML interface This commit enables SAML service providers to make requests using vectors of trust. Vectors of trust support has been built into OIDC in previous commits and much of the work to support this feature was done there. This commit usee the changes in https://github.com/18F/saml_idp/pull/91 to capture the VTR and store it in the service provider request (and eventually `sp_session`). This is done in the `FederateProtocols::Saml` model similar to the approach for OIDC. This commit modifies `SamlRequestValidator` to validate VTRs alongside validations that exist today for `AuthnContextClassref`s. The `Vot::Parser` is used here to validate the format of VoTs. The `SamlRequestValidator` validates that an SP is allowed to make requests with identity proofing if it is requested. Finally the `SamlRequestValidator` will also fail if the vector or trust feature is not available in the environment The logic for biometric comparison was added to `SamlIdpController` to support the `Pb` component-value that can be used there now. Users are prompted to go through proofing with a selfie if it is required. This includes users who have proofed without a selfie.. If the biometric comparison feature is not enabled for the environment and it is requested with the `Pb` component value `SamlIdpController` will render a 406 similar to the `OpenidConnect::AuthorizationController`. changelog: Internal, SAML, VTR support was added to SAML --- Gemfile | 2 +- Gemfile.lock | 6 +- .../concerns/saml_idp_auth_concern.rb | 20 +- app/controllers/saml_idp_controller.rb | 34 +++- app/models/federated_protocols/saml.rb | 2 +- app/services/saml_request_validator.rb | 42 +++- spec/controllers/saml_idp_controller_spec.rb | 133 ++++++++++++- spec/features/saml/vtr_spec.rb | 186 ++++++++++++++++++ spec/services/saml_request_validator_spec.rb | 87 ++++++++ spec/support/fake_saml_request.rb | 4 + 10 files changed, 472 insertions(+), 44 deletions(-) create mode 100644 spec/features/saml/vtr_spec.rb diff --git a/Gemfile b/Gemfile index c4f6ba6d09c..475f83a3c66 100644 --- a/Gemfile +++ b/Gemfile @@ -69,7 +69,7 @@ gem 'rqrcode' gem 'ruby-progressbar' gem 'ruby-saml' gem 'safe_target_blank', '>= 1.0.2' -gem 'saml_idp', github: '18F/saml_idp', tag: '0.18.3-18f' +gem 'saml_idp', github: '18F/saml_idp', tag: '0.19.1-18f' gem 'scrypt' gem 'simple_form', '>= 5.0.2' gem 'stringex', require: false diff --git a/Gemfile.lock b/Gemfile.lock index 0d1b4687ec3..a74bcb992f0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -34,10 +34,10 @@ GIT GIT remote: https://github.com/18F/saml_idp.git - revision: 26d550cd249e52304aecbb53add32cbec4001e2f - tag: 0.18.3-18f + revision: f7dd59de0c860e9d78ab4f05e8365153a2a9b25a + tag: 0.19.1-18f specs: - saml_idp (0.18.3.pre.18f) + saml_idp (0.19.1.pre.18f) activesupport builder faraday diff --git a/app/controllers/concerns/saml_idp_auth_concern.rb b/app/controllers/concerns/saml_idp_auth_concern.rb index 531cae6543d..4ac01f23005 100644 --- a/app/controllers/concerns/saml_idp_auth_concern.rb +++ b/app/controllers/concerns/saml_idp_auth_concern.rb @@ -7,6 +7,7 @@ module SamlIdpAuthConcern # rubocop:disable Rails/LexicallyScopedActionFilter before_action :validate_and_create_saml_request_object, only: :auth before_action :validate_service_provider_and_authn_context, only: :auth + before_action :block_biometric_requests_in_production, only: :auth before_action :check_sp_active, only: :auth before_action :log_external_saml_auth_request, only: [:auth] # this must take place _before_ the store_saml_request action or the SAML @@ -19,6 +20,13 @@ module SamlIdpAuthConcern private + def block_biometric_requests_in_production + if @saml_request_validator.parsed_vector_of_trust&.biometric_comparison? && + !FeatureManagement.idv_allow_selfie_check? + render_not_acceptable + end + end + def sign_out_if_forceauthn_is_true_and_user_is_signed_in if !saml_request.force_authn? set_issuer_forced_reauthentication( @@ -139,21 +147,11 @@ def link_identity_from_session_data end def identity_needs_verification? - ial2_requested? && + resolved_authn_context_result.identity_proofing? && (current_user.identity_not_verified? || current_user.reproof_for_irs?(service_provider: current_sp)) end - def_delegators :ial_context, :ial2_requested? - - def ial_context - @ial_context ||= IalContext.new( - ial: resolved_authn_context_int_ial, - service_provider: saml_request_service_provider, - user: current_user, - ) - end - def active_identity current_user.last_identity end diff --git a/app/controllers/saml_idp_controller.rb b/app/controllers/saml_idp_controller.rb index d3265294ac8..98c879a6de1 100644 --- a/app/controllers/saml_idp_controller.rb +++ b/app/controllers/saml_idp_controller.rb @@ -30,10 +30,11 @@ class SamlIdpController < ApplicationController def auth capture_analytics - if ial_context.ial2_or_greater? + if resolved_authn_context_result.identity_proofing? return redirect_to reactivate_account_url if user_needs_to_reactivate_account? return redirect_to url_for_pending_profile_reason if user_has_pending_profile? return redirect_to idv_url if identity_needs_verification? + return redirect_to idv_url if selfie_needed? end return redirect_to sign_up_completed_url if needs_completion_screen_reason if auth_count == 1 && first_visit_for_sp? @@ -109,6 +110,11 @@ def prompt_for_password_if_ial2_request_and_pii_locked redirect_to capture_password_url end + def selfie_needed? + decorated_sp_session.selfie_required? && + !current_user.identity_verified_with_selfie? + end + def set_devise_failure_redirect_for_concurrent_session_logout request.env['devise_session_limited_failure_redirect_url'] = request.url end @@ -169,6 +175,23 @@ def render_template_for(message, action_url, type) ) end + def track_events + analytics.sp_redirect_initiated( + ial: resolved_authn_context_int_ial, + billed_ial: ial_context.bill_for_ial_1_or_2, + sign_in_flow: session[:sign_in_flow], + ) + track_billing_events + end + + def ial_context + @ial_context ||= IalContext.new( + ial: resolved_authn_context_int_ial, + service_provider: saml_request_service_provider, + user: current_user, + ) + end + def resolved_authn_context_int_ial if resolved_authn_context_result.ialmax? 0 @@ -179,15 +202,6 @@ def resolved_authn_context_int_ial end end - def track_events - analytics.sp_redirect_initiated( - ial: resolved_authn_context_int_ial, - billed_ial: ial_context.bill_for_ial_1_or_2, - sign_in_flow: session[:sign_in_flow], - ) - track_billing_events - end - def require_path_year render_not_found if params[:path_year].blank? end diff --git a/app/models/federated_protocols/saml.rb b/app/models/federated_protocols/saml.rb index 1187b133d36..43ab83c5f22 100644 --- a/app/models/federated_protocols/saml.rb +++ b/app/models/federated_protocols/saml.rb @@ -25,7 +25,7 @@ def acr_values end def vtr - nil + [request.requested_vtr_authn_context] if request.requested_vtr_authn_context.present? end def requested_attributes diff --git a/app/services/saml_request_validator.rb b/app/services/saml_request_validator.rb index c54666b6cb1..b3c0599d244 100644 --- a/app/services/saml_request_validator.rb +++ b/app/services/saml_request_validator.rb @@ -4,6 +4,7 @@ class SamlRequestValidator validate :cert_exists validate :authorized_service_provider validate :authorized_authn_context + validate :parsable_vtr validate :authorized_email_nameid_format def initialize(blank_cert: false) @@ -19,6 +20,16 @@ def call(service_provider:, authn_context:, nameid_format:, authn_context_compar FormResponse.new(success: valid?, errors: errors, extra: extra_analytics_attributes) end + def parsed_vector_of_trust + return @parsed_vector_of_trust if defined?(@parsed_vector_of_trust) + + @parsed_vector_of_trust = begin + Vot::Parser.new(vector_of_trust: vtr.first).parse if !vtr.blank? + rescue Vot::Parser::ParseException + nil + end + end + private attr_accessor :service_provider, :authn_context, :authn_context_comparison, :nameid_format @@ -44,13 +55,19 @@ def authorized_service_provider def authorized_authn_context if !valid_authn_context? || - (ial2_context_requested? && service_provider&.ial != 2) || + (identity_proofing_context_requested? && service_provider&.ial != 2) || (ial_max_requested? && !IdentityConfig.store.allowed_ialmax_providers.include?(service_provider&.issuer)) errors.add(:authn_context, :unauthorized_authn_context, type: :unauthorized_authn_context) end end + def parsable_vtr + if !vtr.blank? && parsed_vector_of_trust.blank? + errors.add(:authn_context, :unauthorized_authn_context, type: :unauthorized_authn_context) + end + end + def cert_exists if @blank_cert errors.add(:service_provider, :blank_cert_element_req, type: :blank_cert_element_req) @@ -62,7 +79,9 @@ def valid_authn_context? valid_contexts += Saml::Idp::Constants::PASSWORD_AUTHN_CONTEXT_CLASSREFS if step_up_comparison? authn_contexts = authn_context.reject do |classref| - classref.include?(Saml::Idp::Constants::REQUESTED_ATTRIBUTES_CLASSREF) + next true if classref.include?(Saml::Idp::Constants::REQUESTED_ATTRIBUTES_CLASSREF) + next true if classref.match?(SamlIdp::Request::VTR_REGEXP) && + IdentityConfig.store.use_vot_in_sp_requests end authn_contexts.all? do |classref| valid_contexts.include?(classref) @@ -73,14 +92,17 @@ def step_up_comparison? %w[minimum better].include? authn_context_comparison end - def ial2_context_requested? - case authn_context - when Array - authn_context.any? do |classref| - Saml::Idp::Constants::IAL2_AUTHN_CONTEXTS.include?(classref) - end - else - Saml::Idp::Constants::IAL2_AUTHN_CONTEXTS.include?(authn_context) + def identity_proofing_context_requested? + authn_context.each do |classref| + return true if parsed_vector_of_trust&.identity_proofing? + return true if Saml::Idp::Constants::IAL2_AUTHN_CONTEXTS.include?(classref) + end + false + end + + def vtr + @vtr ||= Array(authn_context).select do |classref| + classref.match?(SamlIdp::Request::VTR_REGEXP) end end diff --git a/spec/controllers/saml_idp_controller_spec.rb b/spec/controllers/saml_idp_controller_spec.rb index 7acf57c79ec..744d1ef5868 100644 --- a/spec/controllers/saml_idp_controller_spec.rb +++ b/spec/controllers/saml_idp_controller_spec.rb @@ -523,6 +523,14 @@ def name_id_version(format_urn) let(:xmldoc) { SamlResponseDoc.new('controller', 'response_assertion', response) } let(:aal_level) { 1 } + let(:identity_proofing_vtr_settings) do + saml_settings( + overrides: { + issuer: sp1_issuer, + authn_context: 'C1.C2.P1', + }, + ) + end let(:ial2_settings) do saml_settings( overrides: { @@ -541,15 +549,124 @@ def name_id_version(format_urn) ) end - context 'with IAL2 and the identity is already verified' do - let(:ial2_settings) do - saml_settings( - overrides: { - issuer: sp1_issuer, - authn_context: Saml::Idp::Constants::IAL2_AUTHN_CONTEXT_CLASSREF, - }, - ) + context 'when a request is made with a VTR in the authn context' do + let(:user) { create(:user, :fully_registered) } + + before do + allow(IdentityConfig.store).to receive(:use_vot_in_sp_requests).and_return(true) + stub_sign_in(user) + end + + context 'the request does not require identity proofing' do + it 'redirects the user' do + vtr_settings = saml_settings( + overrides: { + issuer: sp1_issuer, + authn_context: 'C1', + }, + ) + saml_get_auth(vtr_settings) + expect(response).to redirect_to(sign_up_completed_url) + expect(controller.session[:sp][:vtr]).to eq(['C1']) + end end + + context 'the request requires identity proofing' do + it 'redirects to identity proofing' do + vtr_settings = saml_settings( + overrides: { + issuer: sp1_issuer, + authn_context: 'C1.C2.P1', + }, + ) + saml_get_auth(vtr_settings) + expect(response).to redirect_to(idv_url) + expect(controller.session[:sp][:vtr]).to eq(['C1.C2.P1']) + end + end + + context 'the request requires identity proofing with a biometric' do + let(:vtr_settings) do + saml_settings( + overrides: { + issuer: sp1_issuer, + authn_context: 'C1.C2.P1.Pb', + }, + ) + end + let(:pii) do + Pii::Attributes.new_from_hash( + first_name: 'Some', + last_name: 'One', + ssn: '666666666', + ) + end + let(:doc_auth_selfie_capture_enabled) { true } + + before do + allow(IdentityConfig.store).to receive( + :doc_auth_selfie_capture_enabled, + ).and_return( + doc_auth_selfie_capture_enabled, + ) + create(:profile, :active, user: user, pii: pii.to_h) + Pii::Cacher.new(user, controller.user_session).save_decrypted_pii( + pii, + user.reload.active_profile.id, + ) + end + + context 'the user has proofed without a biometric check' do + before do + user.active_profile.update!(idv_level: :legacy_unsupervised) + end + + it 'redirects to identity proofing for a user who is verified without a biometric' do + saml_get_auth(vtr_settings) + expect(response).to redirect_to(idv_url) + expect(controller.session[:sp][:vtr]).to eq(['C1.C2.P1.Pb']) + end + end + + context 'the user has proofed with a biometric check' do + before do + user.active_profile.update!(idv_level: :unsupervised_with_selfie) + end + + it 'does not redirect to proofing' do + saml_get_auth(vtr_settings) + expect(response).to redirect_to(sign_up_completed_url) + expect(controller.session[:sp][:vtr]).to eq(['C1.C2.P1.Pb']) + end + end + + context 'selfie check is disabled for the environment' do + let(:doc_auth_selfie_capture_enabled) { false } + + it 'renders an error' do + saml_get_auth(vtr_settings) + expect(response.status).to eq(406) + end + end + end + + context 'the VTR is not parsable' do + it 'renders an error' do + vtr_settings = saml_settings( + overrides: { + issuer: sp1_issuer, + authn_context: 'Fa.Ke.Va.Lu.E0', + }, + ) + saml_get_auth(vtr_settings) + expect(controller).to render_template('saml_idp/auth/error') + expect(response.status).to eq(400) + expect(response.body).to include(t('errors.messages.unauthorized_authn_context')) + end + end + end + + context 'with IAL2 and the identity is already verified' do let(:user) { create(:profile, :active, :verified).user } let(:pii) do Pii::Attributes.new_from_hash( diff --git a/spec/features/saml/vtr_spec.rb b/spec/features/saml/vtr_spec.rb new file mode 100644 index 00000000000..3d95f889bfc --- /dev/null +++ b/spec/features/saml/vtr_spec.rb @@ -0,0 +1,186 @@ +require 'rails_helper' + +RSpec.feature 'SAML requests using VTR', allowed_extra_analytics: [:*] do + include SamlAuthHelper + include IdvHelper + include DocAuthHelper + include WebAuthnHelper + + let(:use_vot_in_sp_requests) { true } + + before do + allow(IdentityConfig.store).to receive( + :use_vot_in_sp_requests, + ).and_return( + use_vot_in_sp_requests, + ) + end + + scenario 'sign in with VTR request for authentication' do + user = create(:user, :fully_registered) + + visit_saml_authn_request_url( + overrides: { + authn_context: 'C1', + }, + ) + sign_in_live_with_2fa(user) + click_submit_default + click_agree_and_continue + click_submit_default + + expect_successful_saml_redirect + + xmldoc = SamlResponseDoc.new('feature', 'response_assertion') + email = xmldoc.attribute_node_for('email').children.map(&:text).join + + expect(user.email_addresses.first.email).to eq(email) + end + + scenario 'sign in with VTR request for AAL2 disables remember device' do + user = create(:user, :fully_registered) + + # Sign in and remember device + sign_in_user(user) + check t('forms.messages.remember_device') + fill_in_code_with_last_phone_otp + click_submit_default + first(:button, t('links.sign_out')).click + + visit_saml_authn_request_url( + overrides: { + authn_context: 'C1.C2', + }, + ) + sign_in_user(user) + + # MFA is required despite remember device + expect(page).to have_current_path(login_two_factor_path(otp_delivery_preference: :sms)) + fill_in_code_with_last_phone_otp + click_submit_default + + click_submit_default + click_agree_and_continue + click_submit_default + expect_successful_saml_redirect + end + + scenario 'sign in with VTR request for phishing-resistance requires phishing-resistanc auth' do + mock_webauthn_setup_challenge + user = create(:user, :fully_registered) + + visit_saml_authn_request_url( + overrides: { + authn_context: 'C1.Ca', + }, + ) + + sign_in_live_with_2fa(user) + + # More secure MFA is required + expect(page).to have_current_path(authentication_methods_setup_path) + expect(page).to have_content(t('two_factor_authentication.two_factor_aal3_choice_intro')) + + # User must setup phishing-resistant auth + select_2fa_option('webauthn', visible: :all) + fill_in_nickname_and_click_continue + mock_press_button_on_hardware_key_on_setup + + click_agree_and_continue + click_submit_default + expect_successful_saml_redirect + end + + scenario 'sign in with VTR request for HSDP12 auth requires PIV/CAC setup' do + allow(Identity::Hostdata).to receive(:env).and_return('test') + allow(Identity::Hostdata).to receive(:domain).and_return('example.com') + + stub_piv_cac_service + + user = create(:user, :fully_registered) + + visit_saml_authn_request_url( + overrides: { + authn_context: 'C1.Cb', + }, + ) + + sign_in_live_with_2fa(user) + + # More secure MFA is required + expect(page).to have_current_path(authentication_methods_setup_path) + expect(page).to have_content(t('two_factor_authentication.two_factor_hspd12_choice_intro')) + + # User must setup PIV/CAC before continuing + visit setup_piv_cac_path + nonce = piv_cac_nonce_from_form_action + visit_piv_cac_service( + setup_piv_cac_url, + nonce: nonce, + uuid: SecureRandom.uuid, + subject: 'SomeIgnoredSubject', + ) + + click_submit_default + click_agree_and_continue + click_submit_default + expect_successful_saml_redirect + end + + scenario 'sign in with VTR request for idv requires idv', :js do + user = create(:user, :fully_registered) + + visit_saml_authn_request_url( + overrides: { + issuer: sp1_issuer, + authn_context: 'C1.C2.P1', + }, + ) + sign_in_live_with_2fa(user) + + expect(page).to have_current_path(idv_welcome_path) + + complete_all_doc_auth_steps_before_password_step(with_selfie: false) + fill_in 'Password', with: user.password + click_continue + acknowledge_and_confirm_personal_key + click_agree_and_continue + + expect_successful_saml_redirect + end + + scenario 'sign in with VTR request for idv with biometric requires idv with biometric', :js do + allow(IdentityConfig.store).to receive(:doc_auth_selfie_capture_enabled).and_return(true) + + user = create(:user, :proofed) + user.active_profile.update!(idv_level: :legacy_unsupervised) + + visit_saml_authn_request_url( + overrides: { + issuer: sp1_issuer, + authn_context: 'C1.C2.P1.Pb', + }, + ) + sign_in_live_with_2fa(user) + + expect(page).to have_current_path(idv_welcome_path) + + complete_all_doc_auth_steps_before_password_step(with_selfie: true) + fill_in 'Password', with: user.password + click_continue + acknowledge_and_confirm_personal_key + click_agree_and_continue + + expect_successful_saml_redirect + end + + def expect_successful_saml_redirect + if javascript_enabled? + expect(current_path).to eq(test_saml_decode_assertion_path) + else + expect(page).to have_current_path( + api_saml_finalauthpost_path(path_year: SamlAuthHelper::PATH_YEAR), + ) + end + end +end diff --git a/spec/services/saml_request_validator_spec.rb b/spec/services/saml_request_validator_spec.rb index ee0788b60a0..e4b63023f75 100644 --- a/spec/services/saml_request_validator_spec.rb +++ b/spec/services/saml_request_validator_spec.rb @@ -23,6 +23,15 @@ ) end + let(:use_vot_in_sp_requests) { true } + before do + allow(IdentityConfig.store).to receive( + :use_vot_in_sp_requests, + ).and_return( + use_vot_in_sp_requests, + ) + end + context 'valid authn context and sp and authorized nameID format' do it 'returns FormResponse with success: true' do expect(response.to_h).to include( @@ -249,5 +258,83 @@ ) end end + + context 'valid VTR and valid SP' do + let(:authn_context) { ['C1'] } + + it 'returns FormResponse with success true' do + expect(response.to_h).to include( + success: true, + errors: {}, + **extra, + ) + end + end + + context 'valid VTR for identity proofing with authorized SP for identity proofing' do + let(:authn_context) { ['C1.P1'] } + before { sp.update!(ial: 2) } + + it 'returns FormResponse with success true' do + expect(response.to_h).to include( + success: true, + errors: {}, + **extra, + ) + end + end + + context 'valid VTR for identity proofing with unauthorized SP for identity proofing' do + let(:authn_context) { ['C1.P1'] } + before { sp.update!(ial: 1) } + + it 'returns FormResponse with success false' do + errors = { + authn_context: [t('errors.messages.unauthorized_authn_context')], + } + + expect(response.to_h).to include( + success: false, + errors: errors, + error_details: hash_including(*errors.keys), + **extra, + ) + end + end + + context 'valid VTR but VTR is disallowed by config' do + let(:use_vot_in_sp_requests) { false } + let(:authn_context) { ['C1'] } + + it 'returns FormResponse with success false' do + errors = { + authn_context: [t('errors.messages.unauthorized_authn_context')], + } + + expect(response.to_h).to include( + success: false, + errors: errors, + error_details: hash_including(*errors.keys), + **extra, + ) + end + end + + context 'unparsable VTR' do + let(:authn_context) { ['Fa.Ke.Va.Lu.E0'] } + + it 'returns FormResponse with success false' do + errors = { + authn_context: [t('errors.messages.unauthorized_authn_context')], + } + + expect(response.to_h).to include( + success: false, + errors: errors, + error_details: hash_including(*errors.keys), + **extra, + ) + end + end end end diff --git a/spec/support/fake_saml_request.rb b/spec/support/fake_saml_request.rb index d0f03628d48..02e6b633417 100644 --- a/spec/support/fake_saml_request.rb +++ b/spec/support/fake_saml_request.rb @@ -38,6 +38,10 @@ def requested_aal_authn_context Saml::Idp::Constants::AAL2_AUTHN_CONTEXT_CLASSREF end + def requested_vtr_authn_context + nil + end + def valid? true end From 279340c63cb2fcde853d6f3d14c2b84bff5ded5b Mon Sep 17 00:00:00 2001 From: Jonathan Hooper Date: Tue, 5 Mar 2024 09:53:09 -0500 Subject: [PATCH 2/2] pr feedback --- app/services/saml_request_validator.rb | 7 ++++--- spec/controllers/saml_idp_controller_spec.rb | 8 -------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/app/services/saml_request_validator.rb b/app/services/saml_request_validator.rb index b3c0599d244..c1e7dda0f98 100644 --- a/app/services/saml_request_validator.rb +++ b/app/services/saml_request_validator.rb @@ -55,7 +55,7 @@ def authorized_service_provider def authorized_authn_context if !valid_authn_context? || - (identity_proofing_context_requested? && service_provider&.ial != 2) || + (identity_proofing_requested? && service_provider&.ial != 2) || (ial_max_requested? && !IdentityConfig.store.allowed_ialmax_providers.include?(service_provider&.issuer)) errors.add(:authn_context, :unauthorized_authn_context, type: :unauthorized_authn_context) @@ -92,9 +92,10 @@ def step_up_comparison? %w[minimum better].include? authn_context_comparison end - def identity_proofing_context_requested? + def identity_proofing_requested? + return true if parsed_vector_of_trust&.identity_proofing? + authn_context.each do |classref| - return true if parsed_vector_of_trust&.identity_proofing? return true if Saml::Idp::Constants::IAL2_AUTHN_CONTEXTS.include?(classref) end false diff --git a/spec/controllers/saml_idp_controller_spec.rb b/spec/controllers/saml_idp_controller_spec.rb index 744d1ef5868..b4b8bf73955 100644 --- a/spec/controllers/saml_idp_controller_spec.rb +++ b/spec/controllers/saml_idp_controller_spec.rb @@ -523,14 +523,6 @@ def name_id_version(format_urn) let(:xmldoc) { SamlResponseDoc.new('controller', 'response_assertion', response) } let(:aal_level) { 1 } - let(:identity_proofing_vtr_settings) do - saml_settings( - overrides: { - issuer: sp1_issuer, - authn_context: 'C1.C2.P1', - }, - ) - end let(:ial2_settings) do saml_settings( overrides: {