diff --git a/app/forms/openid_connect_authorize_form.rb b/app/forms/openid_connect_authorize_form.rb index 40ce4cebb06..0b3d7b3aa65 100644 --- a/app/forms/openid_connect_authorize_form.rb +++ b/app/forms/openid_connect_authorize_form.rb @@ -80,6 +80,7 @@ def link_identity_to_service_provider(current_user, rails_session_id) nonce: nonce, rails_session_id: rails_session_id, ial: ial_context.ial, + aal: aal, scope: scope.join(' '), code_challenge: code_challenge, ) @@ -96,10 +97,6 @@ def ial_values acr_values.filter { |acr| %r{/ial/}.match?(acr) || %r{/loa/}.match?(acr) } end - def aal_values - acr_values.filter { |acr| %r{/aal/}.match? acr } - end - def ial_context @ial_context ||= IalContext.new(ial: ial, service_provider: service_provider) end @@ -108,6 +105,14 @@ def ial Saml::Idp::Constants::AUTHN_CONTEXT_CLASSREF_TO_IAL[ial_values.sort.max] end + def aal_values + acr_values.filter { |acr| %r{/aal/}.match? acr } + end + + def aal + Saml::Idp::Constants::AUTHN_CONTEXT_CLASSREF_TO_AAL[aal_values.sort.max] + end + def_delegators :ial_context, :ial2_or_greater?, :ial2_requested? diff --git a/app/presenters/openid_connect_user_info_presenter.rb b/app/presenters/openid_connect_user_info_presenter.rb index 7f52a4aebc1..edd9e71cb15 100644 --- a/app/presenters/openid_connect_user_info_presenter.rb +++ b/app/presenters/openid_connect_user_info_presenter.rb @@ -21,6 +21,8 @@ def user_info info.merge!(ial2_attributes) if scoper.ial2_scopes_requested? info.merge!(x509_attributes) if scoper.x509_scopes_requested? info[:verified_at] = verified_at if scoper.verified_at_requested? + info[:ial] = identity.ial if identity.ial.present? + info[:aal] = identity.aal if identity.aal.present? scoper.filter(info) end diff --git a/app/services/identity_linker.rb b/app/services/identity_linker.rb index d8d8a06c07f..c1c79dae6f0 100644 --- a/app/services/identity_linker.rb +++ b/app/services/identity_linker.rb @@ -5,11 +5,13 @@ def initialize(user, service_provider) @user = user @service_provider = service_provider @ial = nil + @aal = nil end def link_identity( code_challenge: nil, ial: nil, + aal: nil, nonce: nil, rails_session_id: nil, scope: nil, @@ -18,12 +20,14 @@ def link_identity( clear_deleted_at: nil ) return unless user && service_provider.present? + process_ial(ial) identity.update!( identity_attributes.merge( code_challenge: code_challenge, ial: ial, + aal: aal, nonce: nonce, rails_session_id: rails_session_id, scope: scope, diff --git a/db/primary_migrate/20230126195401_add_aal_to_identities.rb b/db/primary_migrate/20230126195401_add_aal_to_identities.rb new file mode 100644 index 00000000000..af97abb7def --- /dev/null +++ b/db/primary_migrate/20230126195401_add_aal_to_identities.rb @@ -0,0 +1,5 @@ +class AddAalToIdentities < ActiveRecord::Migration[7.0] + def change + add_column :identities, :aal, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index 82b20597939..83e88bb02b4 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2023_01_13_202809) do +ActiveRecord::Schema[7.0].define(version: 2023_01_26_195401) do # These are extensions that must be enabled in order to support this database enable_extension "pg_stat_statements" enable_extension "pgcrypto" @@ -272,6 +272,7 @@ t.datetime "last_ial1_authenticated_at", precision: nil t.datetime "last_ial2_authenticated_at", precision: nil t.datetime "deleted_at", precision: nil + t.integer "aal" t.index ["access_token"], name: "index_identities_on_access_token", unique: true t.index ["session_uuid"], name: "index_identities_on_session_uuid", unique: true t.index ["user_id", "service_provider"], name: "index_identities_on_user_id_and_service_provider", unique: true diff --git a/spec/features/openid_connect/openid_connect_spec.rb b/spec/features/openid_connect/openid_connect_spec.rb index b29b985bfb8..08890f1ed4c 100644 --- a/spec/features/openid_connect/openid_connect_spec.rb +++ b/spec/features/openid_connect/openid_connect_spec.rb @@ -962,6 +962,7 @@ def oidc_end_client_secret_jwt(prompt: nil, user: nil, redirs_to: nil) expect(decoded_id_token[:email]).to eq(user.email) expect(decoded_id_token[:given_name]).to eq('John') expect(decoded_id_token[:social_security_number]).to eq('111223333') + expect(decoded_id_token[:ial]).to eq(2) access_token = token_response[:access_token] expect(access_token).to be_present