diff --git a/app/controllers/concerns/saml_idp_auth_concern.rb b/app/controllers/concerns/saml_idp_auth_concern.rb index 45630305257..b09122ae8d5 100644 --- a/app/controllers/concerns/saml_idp_auth_concern.rb +++ b/app/controllers/concerns/saml_idp_auth_concern.rb @@ -71,8 +71,8 @@ def default_authn_context end def default_aal_context - if current_service_provider.aal - Saml::Idp::Constants::AUTHN_CONTEXT_AAL_TO_CLASSREF[current_service_provider.aal] + if current_service_provider.default_aal + Saml::Idp::Constants::AUTHN_CONTEXT_AAL_TO_CLASSREF[current_service_provider.default_aal] else Saml::Idp::Constants::DEFAULT_AAL_AUTHN_CONTEXT_CLASSREF end diff --git a/app/decorators/service_provider_session_decorator.rb b/app/decorators/service_provider_session_decorator.rb index 243fac9dabc..4601fdc5118 100644 --- a/app/decorators/service_provider_session_decorator.rb +++ b/app/decorators/service_provider_session_decorator.rb @@ -149,7 +149,7 @@ def requested_more_recent_verification? attr_reader :sp, :view_context, :sp_session, :service_provider_request def sp_aal - sp.aal || 1 + sp.default_aal || 1 end def sp_ial diff --git a/app/models/null_service_provider.rb b/app/models/null_service_provider.rb index a3c29a7c836..1ed8e41613c 100644 --- a/app/models/null_service_provider.rb +++ b/app/models/null_service_provider.rb @@ -16,6 +16,7 @@ class NullServiceProvider block_encryption cert created_at + default_aal description failure_to_proof_url fingerprint diff --git a/app/policies/service_provider_mfa_policy.rb b/app/policies/service_provider_mfa_policy.rb index 6a4fe99c608..4ab04824d11 100644 --- a/app/policies/service_provider_mfa_policy.rb +++ b/app/policies/service_provider_mfa_policy.rb @@ -43,7 +43,9 @@ def auth_method_confirms_to_sp_request? end def aal3_required? - aal3_requested? || service_provider&.aal == 3 + return aal3_requested? if aal_requested? + + service_provider&.default_aal == 3 end def piv_cac_required? @@ -62,6 +64,10 @@ def aal3_enabled? piv_cac_enabled? || webauthn_enabled? end + def aal_requested? + @aal_level_requested.present? + end + def aal3_requested? @aal_level_requested == 3 end diff --git a/app/services/attribute_asserter.rb b/app/services/attribute_asserter.rb index dc1692b3fb6..85c30e89383 100644 --- a/app/services/attribute_asserter.rb +++ b/app/services/attribute_asserter.rb @@ -82,7 +82,7 @@ def add_verified_at(attrs) def add_aal(attrs) requested_context = authn_request.requested_aal_authn_context requested_aal_level = Saml::Idp::Constants::AUTHN_CONTEXT_CLASSREF_TO_AAL[requested_context] - aal_level = requested_aal_level || service_provider.aal || ::Idp::Constants::DEFAULT_AAL + aal_level = requested_aal_level || service_provider.default_aal || ::Idp::Constants::DEFAULT_AAL context = Saml::Idp::Constants::AUTHN_CONTEXT_AAL_TO_CLASSREF[aal_level] attrs[:aal] = { getter: aal_getter_function(context) } if context end diff --git a/config/service_providers.localdev.yml b/config/service_providers.localdev.yml index 2575f765dd0..97b6d0a8433 100644 --- a/config/service_providers.localdev.yml +++ b/config/service_providers.localdev.yml @@ -55,7 +55,7 @@ test: cert: 'saml_test_sp' logo: 'generic.svg' ial: 2 - aal: 3 + default_aal: 3 attribute_bundle: - first_name - last_name @@ -183,7 +183,7 @@ test: friendly_name: 'Test SP' assertion_consumer_logout_service_url: '' ial: 2 - aal: 3 + default_aal: 3 allow_prompt_login: true 'test_sp_with_default_help_text': diff --git a/db/migrate/20210120220857_add_default_aal_to_service_provider.rb b/db/migrate/20210120220857_add_default_aal_to_service_provider.rb new file mode 100644 index 00000000000..503654cc420 --- /dev/null +++ b/db/migrate/20210120220857_add_default_aal_to_service_provider.rb @@ -0,0 +1,12 @@ +class AddDefaultAalToServiceProvider < ActiveRecord::Migration[6.1] + def up + add_column :service_providers, :default_aal, :integer + ServiceProvider.all.each do |sp| + sp.update!(default_aal: sp.aal) if sp.aal + end + end + + def down + remove_column :service_providers, :default_aal + end +end diff --git a/db/schema.rb b/db/schema.rb index 34ab4dff049..9f90e5865c0 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -2,15 +2,15 @@ # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. # -# This file is the source Rails uses to define your schema when running `rails -# db:schema:load`. When creating a new database, `rails db:schema:load` tends to +# This file is the source Rails uses to define your schema when running `bin/rails +# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to # be faster and is potentially less error prone than running all of your # migrations from scratch. Old migrations may fail to apply correctly if those # migrations use external dependencies or application code. # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_12_07_191837) do +ActiveRecord::Schema.define(version: 2021_01_20_220857) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -166,12 +166,12 @@ t.integer "choose_method_view_count", default: 0 t.datetime "present_cac_view_at" t.integer "present_cac_view_count", default: 0 + t.integer "present_cac_submit_count", default: 0 + t.integer "present_cac_error_count", default: 0 t.datetime "enter_info_view_at" t.integer "enter_info_view_count", default: 0 t.datetime "success_view_at" t.integer "success_view_count", default: 0 - t.integer "present_cac_submit_count", default: 0 - t.integer "present_cac_error_count", default: 0 t.datetime "selfie_view_at" t.integer "selfie_view_count", default: 0 t.integer "selfie_submit_count", default: 0 @@ -492,6 +492,7 @@ t.date "iaa_start_date" t.date "iaa_end_date" t.string "app_id" + t.integer "default_aal" t.index ["issuer"], name: "index_service_providers_on_issuer", unique: true end diff --git a/spec/decorators/service_provider_session_decorator_spec.rb b/spec/decorators/service_provider_session_decorator_spec.rb index b89709ed6ef..a5d1d083f8c 100644 --- a/spec/decorators/service_provider_session_decorator_spec.rb +++ b/spec/decorators/service_provider_session_decorator_spec.rb @@ -252,7 +252,7 @@ describe '#mfa_expiration_interval' do context 'with an AAL2 sp' do before do - allow(sp).to receive(:aal).and_return(2) + allow(sp).to receive(:default_aal).and_return(2) end it { expect(subject.mfa_expiration_interval).to eq(12.hours) } diff --git a/spec/features/openid_connect/aal3_required_spec.rb b/spec/features/openid_connect/aal3_required_spec.rb index f3d48dd7146..78d6795c931 100644 --- a/spec/features/openid_connect/aal3_required_spec.rb +++ b/spec/features/openid_connect/aal3_required_spec.rb @@ -35,12 +35,12 @@ end end - describe 'ServiceProvider configured to require AAL3 authentication' do + describe 'ServiceProvider configured to default to AAL3 authentication' do context 'user does not have aal3 auth configured' do it 'sends user to set up AAL3 auth' do user = user_with_2fa - visit_idp_from_ial1_oidc_sp_requiring_aal3(prompt: 'select_account') + visit_idp_from_ial1_oidc_sp_defaulting_to_aal3(prompt: 'select_account') sign_in_live_with_2fa(user) expect(current_url).to eq(two_factor_options_url) @@ -52,7 +52,7 @@ context 'user has aal3 auth configured' do it 'sends user to authenticate with AAL3 auth' do sign_in_before_2fa(user_with_aal3_2fa) - visit_idp_from_ial1_oidc_sp_requiring_aal3(prompt: 'select_account') + visit_idp_from_ial1_oidc_sp_defaulting_to_aal3(prompt: 'select_account') visit login_two_factor_path(otp_delivery_preference: 'sms') expect(current_url).to eq(login_two_factor_webauthn_url) @@ -60,7 +60,7 @@ it 'does not allow an already signed in user to bypass AAL3 auth' do sign_in_and_2fa_user(user_with_aal3_2fa) - visit_idp_from_ial1_oidc_sp_requiring_aal3(prompt: 'select_account') + visit_idp_from_ial1_oidc_sp_defaulting_to_aal3(prompt: 'select_account') expect(current_url).to eq(login_two_factor_webauthn_url) end diff --git a/spec/features/remember_device/sp_expiration_spec.rb b/spec/features/remember_device/sp_expiration_spec.rb index 774084dcae0..8f06a94177b 100644 --- a/spec/features/remember_device/sp_expiration_spec.rb +++ b/spec/features/remember_device/sp_expiration_spec.rb @@ -85,11 +85,11 @@ allow(AppConfig.env).to receive(:otp_delivery_blocklist_maxretry).and_return('1000') ServiceProvider.from_issuer('urn:gov:gsa:openidconnect:sp:server').update!( - aal: aal, + default_aal: aal, ial: ial, ) ServiceProvider.from_issuer('http://localhost:3000').update!( - aal: aal, + default_aal: aal, ial: ial, ) end diff --git a/spec/features/saml/aal3_required_spec.rb b/spec/features/saml/aal3_required_spec.rb index 60e393d9ab8..6bb3b07cc84 100644 --- a/spec/features/saml/aal3_required_spec.rb +++ b/spec/features/saml/aal3_required_spec.rb @@ -15,7 +15,7 @@ end end - describe 'SAML ServiceProvider configured to require AAL3 authentication' do + describe 'SAML ServiceProvider configured to default to AAL3 authentication' do context 'user does not have aal3 auth configured' do it 'sends user to set up AAL3 auth' do sign_in_and_2fa_user(user_with_2fa) diff --git a/spec/features/sign_in/remember_device_default_spec.rb b/spec/features/sign_in/remember_device_default_spec.rb index f59e699bb89..8c65f43d08b 100644 --- a/spec/features/sign_in/remember_device_default_spec.rb +++ b/spec/features/sign_in/remember_device_default_spec.rb @@ -15,7 +15,7 @@ context 'when signing in from an SP when the SP is AAL2' do before do ServiceProvider.from_issuer('urn:gov:gsa:openidconnect:sp:server').update!( - aal: 2, + default_aal: 2, ) end diff --git a/spec/features/users/sign_up_spec.rb b/spec/features/users/sign_up_spec.rb index a0bee5aa063..e5ce454662b 100644 --- a/spec/features/users/sign_up_spec.rb +++ b/spec/features/users/sign_up_spec.rb @@ -315,7 +315,7 @@ it 'does not show the remember device option as the default when the SP is AAL2' do ServiceProvider.from_issuer('urn:gov:gsa:openidconnect:sp:server').update!( - aal: 2, + default_aal: 2, ) visit_idp_from_sp_with_ial1(:oidc) sign_up_and_set_password diff --git a/spec/policies/service_provider_mfa_policy_spec.rb b/spec/policies/service_provider_mfa_policy_spec.rb index 88c16c362d6..751d11d1c5f 100644 --- a/spec/policies/service_provider_mfa_policy_spec.rb +++ b/spec/policies/service_provider_mfa_policy_spec.rb @@ -17,6 +17,36 @@ ) end + describe '#aal3_required?' do + context 'aal3 requested' do + let(:aal_level_requested) { 3 } + before { service_provider.default_aal = nil } + + it { expect(policy.aal3_required?).to eq(true) } + end + + context 'no aal level requested, SP default is aal3' do + let(:aal_level_requested) { nil } + before { service_provider.default_aal = 3 } + + it { expect(policy.aal3_required?).to eq(true) } + end + + context 'aal2 requested, no default set' do + let(:aal_level_requested) { 2 } + before { service_provider.default_aal = nil } + + it { expect(policy.aal3_required?).to eq(false) } + end + + context 'aal2 level requested, SP default is aal3' do + let(:aal_level_requested) { 2 } + before { service_provider.default_aal = 3 } + + it { expect(policy.aal3_required?).to eq(false) } + end + end + describe '#user_needs_sp_auth_method_verification?' do context 'aal3 required' do let(:aal_level_requested) { 3 } diff --git a/spec/services/attribute_asserter_spec.rb b/spec/services/attribute_asserter_spec.rb index f7a0d73e840..5dc7b6bff82 100644 --- a/spec/services/attribute_asserter_spec.rb +++ b/spec/services/attribute_asserter_spec.rb @@ -21,7 +21,7 @@ ServiceProvider, issuer: 'http://localhost:3000', ial: service_provider_ial, - aal: service_provider_aal, + default_aal: service_provider_aal, liveness_checking_required: false, metadata: {}, ) diff --git a/spec/support/oidc_auth_helper.rb b/spec/support/oidc_auth_helper.rb index 786f75b5078..114d943744e 100644 --- a/spec/support/oidc_auth_helper.rb +++ b/spec/support/oidc_auth_helper.rb @@ -30,7 +30,7 @@ def visit_idp_from_ial1_oidc_sp_requesting_aal3(**args) oidc_path end - def visit_idp_from_ial1_oidc_sp_requiring_aal3(**args) + def visit_idp_from_ial1_oidc_sp_defaulting_to_aal3(**args) args[:client_id] ||= OIDC_AAL3_ISSUER params = ial1_params args oidc_path = openid_connect_authorize_path params diff --git a/spec/support/saml_auth_helper.rb b/spec/support/saml_auth_helper.rb index 296a3bbf559..ca0111b339f 100644 --- a/spec/support/saml_auth_helper.rb +++ b/spec/support/saml_auth_helper.rb @@ -105,6 +105,7 @@ def sp1_saml_settings def aal3_sp1_saml_settings settings = saml_settings.dup + settings.authn_context = nil settings.issuer = 'https://aal3.serviceprovider.com/auth/saml/metadata' settings end