From bc7a24b4919da4c08670c92684429de3f369e844 Mon Sep 17 00:00:00 2001 From: John Bramley <20125855+bramleyjl@users.noreply.github.com> Date: Tue, 26 Nov 2024 16:39:06 -0700 Subject: [PATCH 1/7] adds map sts token duration validation --- lib/map/security_token/errors.rb | 1 + lib/map/security_token/service.rb | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/map/security_token/errors.rb b/lib/map/security_token/errors.rb index d2189e45f56..46709d79f95 100644 --- a/lib/map/security_token/errors.rb +++ b/lib/map/security_token/errors.rb @@ -4,6 +4,7 @@ module MAP module SecurityToken module Errors class ApplicationMismatchError < StandardError; end + class InvalidTokenDurationError < StandardError; end class MissingICNError < StandardError; end end end diff --git a/lib/map/security_token/service.rb b/lib/map/security_token/service.rb index 63c0d026866..9ffd938118d 100644 --- a/lib/map/security_token/service.rb +++ b/lib/map/security_token/service.rb @@ -26,7 +26,7 @@ def token(application:, icn:, cache: true) rescue Common::Exceptions::GatewayTimeout => e Rails.logger.error("#{config.logging_prefix} token failed, gateway timeout", application:, icn:) raise e - rescue Errors::ApplicationMismatchError => e + rescue Errors::ApplicationMismatchError, Errors::InvalidTokenDurationError => e Rails.logger.error(e.message, application:, icn:) raise e rescue Errors::MissingICNError => e @@ -41,7 +41,10 @@ def request_token(application, icn) config.token_path, token_params(application, icn), { 'Content-Type' => 'application/x-www-form-urlencoded' }) - parse_response(response, application, icn) + parsed_response = parse_response(response, application, icn) + if parsed_response[:expiration] > (Time.zone.now + 900) + raise Errors::InvalidTokenDurationError, "#{config.logging_prefix} token failed, token duration exceeds maximum" + end end def parse_and_raise_error(e, icn, application) From fa248c6808a751d448d2fb3233b175506d22dde3 Mon Sep 17 00:00:00 2001 From: John Bramley <20125855+bramleyjl@users.noreply.github.com> Date: Tue, 26 Nov 2024 16:44:27 -0700 Subject: [PATCH 2/7] updates --- lib/map/security_token/configuration.rb | 4 ++++ lib/map/security_token/service.rb | 11 +++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/map/security_token/configuration.rb b/lib/map/security_token/configuration.rb index baccf972fe7..1032799930c 100644 --- a/lib/map/security_token/configuration.rb +++ b/lib/map/security_token/configuration.rb @@ -66,6 +66,10 @@ def client_assertion_patient_id_type 'icn' end + def max_token_duration + 900 + end + def logging_prefix '[MAP][SecurityToken][Service]' end diff --git a/lib/map/security_token/service.rb b/lib/map/security_token/service.rb index 9ffd938118d..a79ee9d7d88 100644 --- a/lib/map/security_token/service.rb +++ b/lib/map/security_token/service.rb @@ -41,9 +41,12 @@ def request_token(application, icn) config.token_path, token_params(application, icn), { 'Content-Type' => 'application/x-www-form-urlencoded' }) - parsed_response = parse_response(response, application, icn) - if parsed_response[:expiration] > (Time.zone.now + 900) + current_time = Time.zone.now + parsed_response = parse_response(response, application, icn, current_time) + if parsed_response[:expiration] > (current_time + config.max_token_duration) raise Errors::InvalidTokenDurationError, "#{config.logging_prefix} token failed, token duration exceeds maximum" + else + parsed_response end end @@ -58,12 +61,12 @@ def parse_and_raise_error(e, icn, application) raise e, "#{message}, status: #{status}, application: #{application}, icn: #{icn}, context: #{context}" end - def parse_response(response, application, icn) + def parse_response(response, application, icn, current_time) response_body = response.body { access_token: response_body['access_token'], - expiration: Time.zone.now + response_body['expires_in'] + expiration: current_time + response_body['expires_in'] } rescue => e message = "#{config.logging_prefix} token failed, response unknown" From 07767fb1b53ee88fc71a1834ae44327305bc7d00 Mon Sep 17 00:00:00 2001 From: John Bramley <20125855+bramleyjl@users.noreply.github.com> Date: Mon, 2 Dec 2024 13:32:29 -0700 Subject: [PATCH 3/7] updates & unit specs --- app/controllers/v0/map_services_controller.rb | 4 +- lib/map/security_token/service.rb | 18 ++--- spec/lib/map/security_token/service_spec.rb | 12 ++++ spec/requests/v0/map_services_spec.rb | 20 +++++- ...ken_service_200_response_invalid_token.yml | 72 +++++++++++++++++++ 5 files changed, 115 insertions(+), 11 deletions(-) create mode 100644 spec/support/vcr_cassettes/map/security_token_service_200_response_invalid_token.yml diff --git a/app/controllers/v0/map_services_controller.rb b/app/controllers/v0/map_services_controller.rb index b796ae041f5..aaa0bdbef66 100644 --- a/app/controllers/v0/map_services_controller.rb +++ b/app/controllers/v0/map_services_controller.rb @@ -11,7 +11,9 @@ def token result = MAP::SecurityToken::Service.new.token(application: params[:application].to_sym, icn:, cache: false) render json: result, status: :ok - rescue Common::Client::Errors::ClientError, Common::Exceptions::GatewayTimeout + rescue Common::Client::Errors::ClientError, + Common::Exceptions::GatewayTimeout, + MAP::SecurityToken::Errors::InvalidTokenDurationError render json: sts_client_error, status: :bad_gateway rescue MAP::SecurityToken::Errors::ApplicationMismatchError render json: application_mismatch_error, status: :bad_request diff --git a/lib/map/security_token/service.rb b/lib/map/security_token/service.rb index a79ee9d7d88..ee0edf89ee5 100644 --- a/lib/map/security_token/service.rb +++ b/lib/map/security_token/service.rb @@ -41,13 +41,7 @@ def request_token(application, icn) config.token_path, token_params(application, icn), { 'Content-Type' => 'application/x-www-form-urlencoded' }) - current_time = Time.zone.now - parsed_response = parse_response(response, application, icn, current_time) - if parsed_response[:expiration] > (current_time + config.max_token_duration) - raise Errors::InvalidTokenDurationError, "#{config.logging_prefix} token failed, token duration exceeds maximum" - else - parsed_response - end + parse_response(response, application, icn) end def parse_and_raise_error(e, icn, application) @@ -61,13 +55,19 @@ def parse_and_raise_error(e, icn, application) raise e, "#{message}, status: #{status}, application: #{application}, icn: #{icn}, context: #{context}" end - def parse_response(response, application, icn, current_time) + def parse_response(response, application, icn) response_body = response.body + if response_body['expires_in'].to_i > config.max_token_duration + raise Errors::InvalidTokenDurationError, + "#{config.logging_prefix} token failed, token duration exceeds maximum" + end { access_token: response_body['access_token'], - expiration: current_time + response_body['expires_in'] + expiration: Time.zone.now + response_body['expires_in'] } + rescue Errors::InvalidTokenDurationError => e + raise e rescue => e message = "#{config.logging_prefix} token failed, response unknown" Rails.logger.error(message, application:, icn:) diff --git a/spec/lib/map/security_token/service_spec.rb b/spec/lib/map/security_token/service_spec.rb index 1ca9a7a6266..acc19175fa3 100644 --- a/spec/lib/map/security_token/service_spec.rb +++ b/spec/lib/map/security_token/service_spec.rb @@ -140,6 +140,18 @@ end end + context 'when response is successful with an invalid token duration', + vcr: { cassette_name: 'map/security_token_service_200_response_invalid_token' } do + let(:expected_error) { MAP::SecurityToken::Errors::InvalidTokenDurationError } + let(:expected_error_message) { "#{log_prefix} token failed, token duration exceeds maximum" } + let(:expected_log_values) { { application:, icn: } } + + it 'raises an invalid token duration error and creates a log' do + expect(Rails.logger).to receive(:error).with(expected_error_message, expected_log_values) + expect { subject }.to raise_exception(expected_error, expected_error_message) + end + end + context 'and response is successful' do let(:expected_log_message) { "#{log_prefix} token success" } let(:expected_log_payload) { { application:, icn:, cached_response: false } } diff --git a/spec/requests/v0/map_services_spec.rb b/spec/requests/v0/map_services_spec.rb index ffc05c67261..8836ff1258a 100644 --- a/spec/requests/v0/map_services_spec.rb +++ b/spec/requests/v0/map_services_spec.rb @@ -93,7 +93,25 @@ end end - context 'when MAP STS client returns an access token', + context 'when MAP STS client returns a token with an invalid duration', + vcr: { cassette_name: 'map/security_token_service_200_response_invalid_token' } do + it 'responds with error details in response body' do + call_endpoint + expect(JSON.parse(response.body)).to eq( + { + 'error' => 'server_error', + 'error_description' => 'STS failed to return a valid token.' + } + ) + end + + it 'returns HTTP status bad_gateway' do + call_endpoint + expect(response).to have_http_status(:bad_gateway) + end + end + + context 'when MAP STS client returns a valid access token', vcr: { cassette_name: 'map/security_token_service_200_response' } do it 'responds with STS-issued token in response body' do call_endpoint diff --git a/spec/support/vcr_cassettes/map/security_token_service_200_response_invalid_token.yml b/spec/support/vcr_cassettes/map/security_token_service_200_response_invalid_token.yml new file mode 100644 index 00000000000..31c1c5fcf80 --- /dev/null +++ b/spec/support/vcr_cassettes/map/security_token_service_200_response_invalid_token.yml @@ -0,0 +1,72 @@ +--- +http_interactions: +- request: + method: post + uri: https://veteran.apps-staging.va.gov/sts/oauth/v1/token + body: + encoding: US-ASCII + string: grant_type=client_credentials&client_id=c7d6e0fc9a39&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=eyJhbGciOiJSUzUxMiJ9.eyJyb2xlIjoidmV0ZXJhbiIsInBhdGllbnRfaWQiOiJzb21lLWljbiIsInBhdGllbnRfaWRfdHlwZSI6ImljbiIsInN1YiI6ImM3ZDZlMGZjOWEzOSIsImp0aSI6IjIwODllOWFlLTZiNDctNGJkNy05NzNiLTczMzM4NjgzYTVkYiIsImlzcyI6ImM3ZDZlMGZjOWEzOSIsImF1ZCI6Imh0dHBzOi8vZ29vZ2xlLmNvbS9zdHMvb2F1dGgvdjEvdG9rZW4iLCJuYmYiOjE2OTI5MjE5NjcsImV4cCI6MTY5MjkyMjI2N30.VXzWaXBjk83TNA39VTApJQSG9inwyUioYouGXeqkEWicSP3oLb-CNFpkEgkMNccz6SpAlYIJ_KYKRFAA1rQv8Gp5LzIv_YM2WFJUYxpF02-fAhYzl6SkOLwD86Yto6a8JbFrNPL9uYxG1vmTZgl_vk2dmNFpnQ3gf8bXc2GOBAM2gc3tzNjv1M18dVtObX6zw7ZG7drxw7itzZnkDLTU9217XyOgSFQvA0czRiiRcfsXb6LIB7A1k7MpQy6KA3UDBQ7sbuXkaFZiJo2tSDG3PXScTHBtqmqejCt68906wiBf_ACeI4TQPH4ogoTrnfb9oprQyKp8xMlwwKYAMih12g + headers: + Accept: + - application/json + Content-Type: + - application/x-www-form-urlencoded + User-Agent: + - Vets.gov Agent + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Content-Type: + - application/json; charset=utf-8 + X-Frame-Options: + - allow-from https://nextgenid-mbetenantworkflow.azurewebsites.net + X-Xss-Protection: + - 1; mode=block + X-Content-Type-Options: + - nosniff + X-Download-Options: + - noopen + X-Permitted-Cross-Domain-Policies: + - none + Referrer-Policy: + - strict-origin-when-cross-origin + Content-Security-Policy: + - frame-ancestors https://nextgenid-mbetenantworkflow.azurewebsites.net + Etag: + - W/"dba68a519b00d7f452e79971a398650f" + X-Request-Id: + - 5b1d220c-4b01-4409-b9a5-367ab3c99ca9 + X-Runtime: + - '0.026178' + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Node: + - sandbox-core-02.idmeinc.net + Vary: + - Accept-Encoding + Expires: + - Wed, 26 Jul 2023 19:56:07 GMT + Cache-Control: + - max-age=0, no-cache, no-store + Pragma: + - no-cache + Date: + - Wed, 26 Jul 2023 19:56:07 GMT + Content-Length: + - '14658' + Connection: + - keep-alive + Server-Timing: + - ak_p; desc="1690401366974_1752320020_1303469004_11342_12901_31_-_-";dur=1 + - cdn-cache; desc=MISS + - edge; dur=68 + - origin; dur=46 + body: + encoding: UTF-8 + string: '{"access_token":"eyJhbGciOiJSUzUxMiJ9.eyJsYXN0TmFtZSI6Im9hdXRoLWNsaWVudCIsInN1YiI6ImM3ZDZlMGZjOWEzOSIsImF1dGhlbnRpY2F0ZWQiOnRydWUsImF1dGhlbnRpY2F0aW9uQXV0aG9yaXR5IjoiZ292LnZhLm1vYmlsZS5vYXV0aC52MSIsImlkVHlwZSI6Ik1PQklMRV9PQVVUSF9TVFNfQ0xJRU5UX0lEIiwiaXNzIjoiZ292LnZhLnZhbWYudXNlcnNlcnZpY2UudjIiLCJvbkJlaGFsZk9mIjp7ImlkVHlwZSI6ImljbiIsImlkIjoiMTAxMjcwNDY4NlYxNTk4ODcifSwidmFtZi5hdXRoLnJlc291cmNlcyI6WyJeLiooXC8pP3NpdGVbc10_XC8oZGZuLSk_NDUzXC9wYXRpZW50W3NdP1wvMzUxODVcL2FwcG9pbnRtZW50cyhcLy4qKT8kIiwiXi4qKFwvKT9wYXRpZW50W3NdP1wvRURJUElcLzE2MDc2OTQ5MDMoXC8uKik_JCIsIl4uKihcLyk_cGF0aWVudFtzXT9cLyhJQ05cLyk_MTAxMjcwNDY4NlYxNTk4ODcoXC8uKik_JCJdLCJ2ZXJzaW9uIjoyLjgsImZpcnN0TmFtZSI6IlZBLmdvdiBTaWdudXAgKFNRQSkiLCJhdWQiOiJjN2Q2ZTBmYzlhMzkiLCJuYmYiOjE2OTI5MjExMTMsInNzdCI6MTY5MjkyMTI5MywidmFtZi5hdXRoLnJvbGVzIjpbInZldGVyYW4iXSwidXNlclR5cGUiOiJvbi1iZWhhbGYtb2YiLCJleHAiOjE2OTI5MjIxOTMsImlhdCI6MTY5MjkyMTI5MywianRpIjoiMzQ2M2I4YjQtM2Y5Zi00ZTZiLWIzYjItNzBlMGEwOGM4OTE4In0.LXAxWbzCmVZEothmkV3CFi5Jitx8MYnmkPSIqOkWghOz2wZJV7SX96bBhZ3zK5xUYlxwQ_ElwKU3otb47IeWK3XflbW1K1m8HbZ5qtKgfofv4sk0xM7UEafRQdmLGQOX0ClqbmMrNss12z5Ay0BSBpltoBGekKyRcwRerhP35o4d0uHKDY8JanhljylZupfO8e5Kpx8R0UfL1rXRXjhAWTbf23oJOB8onvJ_RZz1YHXQU-M34-faj_iHKrms3t9h7n3fhJKYciYOAfxN2feeOpFJ95Zt-mJGARUY3ryeIXFm5HJjL1KTjZ1eB9NmX7H2ST3uqax0PY5biYiiwX1a2g","token_type":"Bearer","expires_in":999}' + recorded_at: Wed, 26 Oct 2022 18:30:02 GMT +recorded_with: VCR 6.1.0 From 6f246bf6f30dec5d3b87fce647b6457c93e03c2d Mon Sep 17 00:00:00 2001 From: John Bramley <20125855+bramleyjl@users.noreply.github.com> Date: Wed, 11 Dec 2024 13:46:17 -0700 Subject: [PATCH 4/7] initial MAP JWT signature validation --- app/controllers/v0/map_services_controller.rb | 4 +- config/settings.yml | 1 + lib/map/security_token/configuration.rb | 12 ++-- lib/map/security_token/errors.rb | 1 - lib/map/security_token/service.rb | 23 ++++-- spec/lib/map/security_token/service_spec.rb | 12 ---- ...ken_service_200_response_invalid_token.yml | 72 ------------------- 7 files changed, 26 insertions(+), 99 deletions(-) delete mode 100644 spec/support/vcr_cassettes/map/security_token_service_200_response_invalid_token.yml diff --git a/app/controllers/v0/map_services_controller.rb b/app/controllers/v0/map_services_controller.rb index aaa0bdbef66..4080a9c420a 100644 --- a/app/controllers/v0/map_services_controller.rb +++ b/app/controllers/v0/map_services_controller.rb @@ -11,9 +11,7 @@ def token result = MAP::SecurityToken::Service.new.token(application: params[:application].to_sym, icn:, cache: false) render json: result, status: :ok - rescue Common::Client::Errors::ClientError, - Common::Exceptions::GatewayTimeout, - MAP::SecurityToken::Errors::InvalidTokenDurationError + rescue Common::Client::Errors::ClientError, Common::Exceptions::GatewayTimeout, JWT::VerificationError render json: sts_client_error, status: :bad_gateway rescue MAP::SecurityToken::Errors::ApplicationMismatchError render json: application_mismatch_error, status: :bad_request diff --git a/config/settings.yml b/config/settings.yml index c8afe037810..fced2c868ae 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -33,6 +33,7 @@ map_services: oauth_url: https://veteran.apps-staging.va.gov client_cert_path: spec/fixtures/map/oauth.crt client_key_path: spec/fixtures/map/oauth.key + provider_cert_path: spec/fixtures/map/provider.crt sign_up_service_url: https://cerner.apps-staging.va.gov sign_up_service_provisioning_api_key: abcd1234 secure_token_service: diff --git a/lib/map/security_token/configuration.rb b/lib/map/security_token/configuration.rb index 1032799930c..4a18830bd56 100644 --- a/lib/map/security_token/configuration.rb +++ b/lib/map/security_token/configuration.rb @@ -34,6 +34,10 @@ def client_cert_path Settings.map_services.client_cert_path end + def provider_cert_path + Settings.map_services.provider_cert_path + end + def service_name 'map_security_token_service' end @@ -66,10 +70,6 @@ def client_assertion_patient_id_type 'icn' end - def max_token_duration - 900 - end - def logging_prefix '[MAP][SecurityToken][Service]' end @@ -82,6 +82,10 @@ def client_assertion_certificate OpenSSL::X509::Certificate.new(File.read(client_cert_path)) end + def provider_certificate + OpenSSL::X509::Certificate.new(File.read(provider_cert_path)) + end + def connection @connection ||= Faraday.new( base_path, diff --git a/lib/map/security_token/errors.rb b/lib/map/security_token/errors.rb index 46709d79f95..d2189e45f56 100644 --- a/lib/map/security_token/errors.rb +++ b/lib/map/security_token/errors.rb @@ -4,7 +4,6 @@ module MAP module SecurityToken module Errors class ApplicationMismatchError < StandardError; end - class InvalidTokenDurationError < StandardError; end class MissingICNError < StandardError; end end end diff --git a/lib/map/security_token/service.rb b/lib/map/security_token/service.rb index ee0edf89ee5..56839f73ff9 100644 --- a/lib/map/security_token/service.rb +++ b/lib/map/security_token/service.rb @@ -26,7 +26,7 @@ def token(application:, icn:, cache: true) rescue Common::Exceptions::GatewayTimeout => e Rails.logger.error("#{config.logging_prefix} token failed, gateway timeout", application:, icn:) raise e - rescue Errors::ApplicationMismatchError, Errors::InvalidTokenDurationError => e + rescue Errors::ApplicationMismatchError => e Rails.logger.error(e.message, application:, icn:) raise e rescue Errors::MissingICNError => e @@ -57,16 +57,15 @@ def parse_and_raise_error(e, icn, application) def parse_response(response, application, icn) response_body = response.body - if response_body['expires_in'].to_i > config.max_token_duration - raise Errors::InvalidTokenDurationError, - "#{config.logging_prefix} token failed, token duration exceeds maximum" - end + access_token = validate_map_token(response_body['access_token']) { - access_token: response_body['access_token'], + access_token:, expiration: Time.zone.now + response_body['expires_in'] } - rescue Errors::InvalidTokenDurationError => e + rescue JWT::VerificationError => e + message = "#{config.logging_prefix} token failed, JWT verification error" + Rails.logger.error(message, application:, icn:) raise e rescue => e message = "#{config.logging_prefix} token failed, response unknown" @@ -74,6 +73,16 @@ def parse_response(response, application, icn) raise e, "#{message}, application: #{application}, icn: #{icn}" end + def validate_map_token(encoded_token) + # waiting for MAP RS512 certificate + # public_cert = config.provider_certificate + public_cert = OpenSSL::PKey::RSA.new(2048).public_key + JWT.decode(encoded_token, public_cert, true, algorithm: 'RS512') + # potentially add more validation here + + access_token + end + def client_id_from_application(application) case application when :chatbot diff --git a/spec/lib/map/security_token/service_spec.rb b/spec/lib/map/security_token/service_spec.rb index acc19175fa3..1ca9a7a6266 100644 --- a/spec/lib/map/security_token/service_spec.rb +++ b/spec/lib/map/security_token/service_spec.rb @@ -140,18 +140,6 @@ end end - context 'when response is successful with an invalid token duration', - vcr: { cassette_name: 'map/security_token_service_200_response_invalid_token' } do - let(:expected_error) { MAP::SecurityToken::Errors::InvalidTokenDurationError } - let(:expected_error_message) { "#{log_prefix} token failed, token duration exceeds maximum" } - let(:expected_log_values) { { application:, icn: } } - - it 'raises an invalid token duration error and creates a log' do - expect(Rails.logger).to receive(:error).with(expected_error_message, expected_log_values) - expect { subject }.to raise_exception(expected_error, expected_error_message) - end - end - context 'and response is successful' do let(:expected_log_message) { "#{log_prefix} token success" } let(:expected_log_payload) { { application:, icn:, cached_response: false } } diff --git a/spec/support/vcr_cassettes/map/security_token_service_200_response_invalid_token.yml b/spec/support/vcr_cassettes/map/security_token_service_200_response_invalid_token.yml deleted file mode 100644 index 31c1c5fcf80..00000000000 --- a/spec/support/vcr_cassettes/map/security_token_service_200_response_invalid_token.yml +++ /dev/null @@ -1,72 +0,0 @@ ---- -http_interactions: -- request: - method: post - uri: https://veteran.apps-staging.va.gov/sts/oauth/v1/token - body: - encoding: US-ASCII - string: grant_type=client_credentials&client_id=c7d6e0fc9a39&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=eyJhbGciOiJSUzUxMiJ9.eyJyb2xlIjoidmV0ZXJhbiIsInBhdGllbnRfaWQiOiJzb21lLWljbiIsInBhdGllbnRfaWRfdHlwZSI6ImljbiIsInN1YiI6ImM3ZDZlMGZjOWEzOSIsImp0aSI6IjIwODllOWFlLTZiNDctNGJkNy05NzNiLTczMzM4NjgzYTVkYiIsImlzcyI6ImM3ZDZlMGZjOWEzOSIsImF1ZCI6Imh0dHBzOi8vZ29vZ2xlLmNvbS9zdHMvb2F1dGgvdjEvdG9rZW4iLCJuYmYiOjE2OTI5MjE5NjcsImV4cCI6MTY5MjkyMjI2N30.VXzWaXBjk83TNA39VTApJQSG9inwyUioYouGXeqkEWicSP3oLb-CNFpkEgkMNccz6SpAlYIJ_KYKRFAA1rQv8Gp5LzIv_YM2WFJUYxpF02-fAhYzl6SkOLwD86Yto6a8JbFrNPL9uYxG1vmTZgl_vk2dmNFpnQ3gf8bXc2GOBAM2gc3tzNjv1M18dVtObX6zw7ZG7drxw7itzZnkDLTU9217XyOgSFQvA0czRiiRcfsXb6LIB7A1k7MpQy6KA3UDBQ7sbuXkaFZiJo2tSDG3PXScTHBtqmqejCt68906wiBf_ACeI4TQPH4ogoTrnfb9oprQyKp8xMlwwKYAMih12g - headers: - Accept: - - application/json - Content-Type: - - application/x-www-form-urlencoded - User-Agent: - - Vets.gov Agent - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - response: - status: - code: 200 - message: OK - headers: - Content-Type: - - application/json; charset=utf-8 - X-Frame-Options: - - allow-from https://nextgenid-mbetenantworkflow.azurewebsites.net - X-Xss-Protection: - - 1; mode=block - X-Content-Type-Options: - - nosniff - X-Download-Options: - - noopen - X-Permitted-Cross-Domain-Policies: - - none - Referrer-Policy: - - strict-origin-when-cross-origin - Content-Security-Policy: - - frame-ancestors https://nextgenid-mbetenantworkflow.azurewebsites.net - Etag: - - W/"dba68a519b00d7f452e79971a398650f" - X-Request-Id: - - 5b1d220c-4b01-4409-b9a5-367ab3c99ca9 - X-Runtime: - - '0.026178' - Strict-Transport-Security: - - max-age=63072000; includeSubDomains - X-Node: - - sandbox-core-02.idmeinc.net - Vary: - - Accept-Encoding - Expires: - - Wed, 26 Jul 2023 19:56:07 GMT - Cache-Control: - - max-age=0, no-cache, no-store - Pragma: - - no-cache - Date: - - Wed, 26 Jul 2023 19:56:07 GMT - Content-Length: - - '14658' - Connection: - - keep-alive - Server-Timing: - - ak_p; desc="1690401366974_1752320020_1303469004_11342_12901_31_-_-";dur=1 - - cdn-cache; desc=MISS - - edge; dur=68 - - origin; dur=46 - body: - encoding: UTF-8 - string: '{"access_token":"eyJhbGciOiJSUzUxMiJ9.eyJsYXN0TmFtZSI6Im9hdXRoLWNsaWVudCIsInN1YiI6ImM3ZDZlMGZjOWEzOSIsImF1dGhlbnRpY2F0ZWQiOnRydWUsImF1dGhlbnRpY2F0aW9uQXV0aG9yaXR5IjoiZ292LnZhLm1vYmlsZS5vYXV0aC52MSIsImlkVHlwZSI6Ik1PQklMRV9PQVVUSF9TVFNfQ0xJRU5UX0lEIiwiaXNzIjoiZ292LnZhLnZhbWYudXNlcnNlcnZpY2UudjIiLCJvbkJlaGFsZk9mIjp7ImlkVHlwZSI6ImljbiIsImlkIjoiMTAxMjcwNDY4NlYxNTk4ODcifSwidmFtZi5hdXRoLnJlc291cmNlcyI6WyJeLiooXC8pP3NpdGVbc10_XC8oZGZuLSk_NDUzXC9wYXRpZW50W3NdP1wvMzUxODVcL2FwcG9pbnRtZW50cyhcLy4qKT8kIiwiXi4qKFwvKT9wYXRpZW50W3NdP1wvRURJUElcLzE2MDc2OTQ5MDMoXC8uKik_JCIsIl4uKihcLyk_cGF0aWVudFtzXT9cLyhJQ05cLyk_MTAxMjcwNDY4NlYxNTk4ODcoXC8uKik_JCJdLCJ2ZXJzaW9uIjoyLjgsImZpcnN0TmFtZSI6IlZBLmdvdiBTaWdudXAgKFNRQSkiLCJhdWQiOiJjN2Q2ZTBmYzlhMzkiLCJuYmYiOjE2OTI5MjExMTMsInNzdCI6MTY5MjkyMTI5MywidmFtZi5hdXRoLnJvbGVzIjpbInZldGVyYW4iXSwidXNlclR5cGUiOiJvbi1iZWhhbGYtb2YiLCJleHAiOjE2OTI5MjIxOTMsImlhdCI6MTY5MjkyMTI5MywianRpIjoiMzQ2M2I4YjQtM2Y5Zi00ZTZiLWIzYjItNzBlMGEwOGM4OTE4In0.LXAxWbzCmVZEothmkV3CFi5Jitx8MYnmkPSIqOkWghOz2wZJV7SX96bBhZ3zK5xUYlxwQ_ElwKU3otb47IeWK3XflbW1K1m8HbZ5qtKgfofv4sk0xM7UEafRQdmLGQOX0ClqbmMrNss12z5Ay0BSBpltoBGekKyRcwRerhP35o4d0uHKDY8JanhljylZupfO8e5Kpx8R0UfL1rXRXjhAWTbf23oJOB8onvJ_RZz1YHXQU-M34-faj_iHKrms3t9h7n3fhJKYciYOAfxN2feeOpFJ95Zt-mJGARUY3ryeIXFm5HJjL1KTjZ1eB9NmX7H2ST3uqax0PY5biYiiwX1a2g","token_type":"Bearer","expires_in":999}' - recorded_at: Wed, 26 Oct 2022 18:30:02 GMT -recorded_with: VCR 6.1.0 From c2afa830d5f4ac4d87fbdff4da6ab493909cc194 Mon Sep 17 00:00:00 2001 From: John Bramley <20125855+bramleyjl@users.noreply.github.com> Date: Fri, 13 Dec 2024 15:57:23 -0700 Subject: [PATCH 5/7] map jwks call --- app/controllers/v0/map_services_controller.rb | 2 +- config/betamocks/services_config.yml | 3 +++ config/settings.yml | 2 +- lib/map/security_token/configuration.rb | 12 +++++++++--- lib/map/security_token/service.rb | 11 +++-------- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/app/controllers/v0/map_services_controller.rb b/app/controllers/v0/map_services_controller.rb index 4080a9c420a..18c792454b5 100644 --- a/app/controllers/v0/map_services_controller.rb +++ b/app/controllers/v0/map_services_controller.rb @@ -11,7 +11,7 @@ def token result = MAP::SecurityToken::Service.new.token(application: params[:application].to_sym, icn:, cache: false) render json: result, status: :ok - rescue Common::Client::Errors::ClientError, Common::Exceptions::GatewayTimeout, JWT::VerificationError + rescue Common::Client::Errors::ClientError, Common::Exceptions::GatewayTimeout, JWT::DecodeError render json: sts_client_error, status: :bad_gateway rescue MAP::SecurityToken::Errors::ApplicationMismatchError render json: application_mismatch_error, status: :bad_request diff --git a/config/betamocks/services_config.yml b/config/betamocks/services_config.yml index 3e29c582c21..4e7124e8236 100644 --- a/config/betamocks/services_config.yml +++ b/config/betamocks/services_config.yml @@ -896,6 +896,9 @@ - :method: :post :path: "/sts/oauth/v1/token" :file_path: "map/secure_token_service/token" + - :method: :get + :path: "/sts/oauth/v1/jwks" + :file_path: "map/secure_token_service/jwks" # Sign Up Service Terms API - :name: "MAP SUS" diff --git a/config/settings.yml b/config/settings.yml index fced2c868ae..fdb86c04902 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -33,7 +33,7 @@ map_services: oauth_url: https://veteran.apps-staging.va.gov client_cert_path: spec/fixtures/map/oauth.crt client_key_path: spec/fixtures/map/oauth.key - provider_cert_path: spec/fixtures/map/provider.crt + provider_jwks_path: /sts/oauth/v1/jwks sign_up_service_url: https://cerner.apps-staging.va.gov sign_up_service_provisioning_api_key: abcd1234 secure_token_service: diff --git a/lib/map/security_token/configuration.rb b/lib/map/security_token/configuration.rb index 4a18830bd56..203b32a05a8 100644 --- a/lib/map/security_token/configuration.rb +++ b/lib/map/security_token/configuration.rb @@ -34,8 +34,8 @@ def client_cert_path Settings.map_services.client_cert_path end - def provider_cert_path - Settings.map_services.provider_cert_path + def provider_jwks_path + Settings.map_services.provider_jwks_path end def service_name @@ -83,7 +83,13 @@ def client_assertion_certificate end def provider_certificate - OpenSSL::X509::Certificate.new(File.read(provider_cert_path)) + @provider_certificate ||= build_provider_certificate + end + + def build_provider_certificate + response = connection.get(provider_jwks_path) + jwk = response.body['keys'].first + JWT::JWK.import(jwk).keypair.public_key end def connection diff --git a/lib/map/security_token/service.rb b/lib/map/security_token/service.rb index 56839f73ff9..dc7f2cf12f5 100644 --- a/lib/map/security_token/service.rb +++ b/lib/map/security_token/service.rb @@ -57,10 +57,10 @@ def parse_and_raise_error(e, icn, application) def parse_response(response, application, icn) response_body = response.body - access_token = validate_map_token(response_body['access_token']) + validate_map_token(response_body['access_token']) { - access_token:, + access_token: response_body['access_token'], expiration: Time.zone.now + response_body['expires_in'] } rescue JWT::VerificationError => e @@ -74,13 +74,8 @@ def parse_response(response, application, icn) end def validate_map_token(encoded_token) - # waiting for MAP RS512 certificate - # public_cert = config.provider_certificate - public_cert = OpenSSL::PKey::RSA.new(2048).public_key + public_cert = config.provider_certificate JWT.decode(encoded_token, public_cert, true, algorithm: 'RS512') - # potentially add more validation here - - access_token end def client_id_from_application(application) From 082452d0a6a9df3c75f237aad3774d41e353d6be Mon Sep 17 00:00:00 2001 From: John Bramley <20125855+bramleyjl@users.noreply.github.com> Date: Tue, 17 Dec 2024 10:00:39 -0700 Subject: [PATCH 6/7] updates map response to a VA.gov-owned keypair --- .../vcr_cassettes/map/security_token_service_200_response.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/support/vcr_cassettes/map/security_token_service_200_response.yml b/spec/support/vcr_cassettes/map/security_token_service_200_response.yml index 14d618ccc38..4b694a324b9 100644 --- a/spec/support/vcr_cassettes/map/security_token_service_200_response.yml +++ b/spec/support/vcr_cassettes/map/security_token_service_200_response.yml @@ -67,6 +67,6 @@ http_interactions: - origin; dur=46 body: encoding: UTF-8 - string: '{"access_token":"eyJhbGciOiJSUzUxMiJ9.eyJsYXN0TmFtZSI6Im9hdXRoLWNsaWVudCIsInN1YiI6ImM3ZDZlMGZjOWEzOSIsImF1dGhlbnRpY2F0ZWQiOnRydWUsImF1dGhlbnRpY2F0aW9uQXV0aG9yaXR5IjoiZ292LnZhLm1vYmlsZS5vYXV0aC52MSIsImlkVHlwZSI6Ik1PQklMRV9PQVVUSF9TVFNfQ0xJRU5UX0lEIiwiaXNzIjoiZ292LnZhLnZhbWYudXNlcnNlcnZpY2UudjIiLCJvbkJlaGFsZk9mIjp7ImlkVHlwZSI6ImljbiIsImlkIjoiMTAxMjcwNDY4NlYxNTk4ODcifSwidmFtZi5hdXRoLnJlc291cmNlcyI6WyJeLiooXC8pP3NpdGVbc10_XC8oZGZuLSk_NDUzXC9wYXRpZW50W3NdP1wvMzUxODVcL2FwcG9pbnRtZW50cyhcLy4qKT8kIiwiXi4qKFwvKT9wYXRpZW50W3NdP1wvRURJUElcLzE2MDc2OTQ5MDMoXC8uKik_JCIsIl4uKihcLyk_cGF0aWVudFtzXT9cLyhJQ05cLyk_MTAxMjcwNDY4NlYxNTk4ODcoXC8uKik_JCJdLCJ2ZXJzaW9uIjoyLjgsImZpcnN0TmFtZSI6IlZBLmdvdiBTaWdudXAgKFNRQSkiLCJhdWQiOiJjN2Q2ZTBmYzlhMzkiLCJuYmYiOjE2OTI5MjExMTMsInNzdCI6MTY5MjkyMTI5MywidmFtZi5hdXRoLnJvbGVzIjpbInZldGVyYW4iXSwidXNlclR5cGUiOiJvbi1iZWhhbGYtb2YiLCJleHAiOjE2OTI5MjIxOTMsImlhdCI6MTY5MjkyMTI5MywianRpIjoiMzQ2M2I4YjQtM2Y5Zi00ZTZiLWIzYjItNzBlMGEwOGM4OTE4In0.LXAxWbzCmVZEothmkV3CFi5Jitx8MYnmkPSIqOkWghOz2wZJV7SX96bBhZ3zK5xUYlxwQ_ElwKU3otb47IeWK3XflbW1K1m8HbZ5qtKgfofv4sk0xM7UEafRQdmLGQOX0ClqbmMrNss12z5Ay0BSBpltoBGekKyRcwRerhP35o4d0uHKDY8JanhljylZupfO8e5Kpx8R0UfL1rXRXjhAWTbf23oJOB8onvJ_RZz1YHXQU-M34-faj_iHKrms3t9h7n3fhJKYciYOAfxN2feeOpFJ95Zt-mJGARUY3ryeIXFm5HJjL1KTjZ1eB9NmX7H2ST3uqax0PY5biYiiwX1a2g","token_type":"Bearer","expires_in":899}' + string: {"access_token":"eyJhbGciOiJSUzUxMiJ9.eyJsYXN0TmFtZSI6Im9hdXRoLWNsaWVudCIsInN1YiI6ImM3ZDZlMGZjOWEzOSIsImF1dGhlbnRpY2F0ZWQiOnRydWUsImF1dGhlbnRpY2F0aW9uQXV0aG9yaXR5IjoiZ292LnZhLm1vYmlsZS5vYXV0aC52MSIsImlkVHlwZSI6Ik1PQklMRV9PQVVUSF9TVFNfQ0xJRU5UX0lEIiwiaXNzIjoiZ292LnZhLnZhbWYudXNlcnNlcnZpY2UudjIiLCJvbkJlaGFsZk9mIjp7ImlkVHlwZSI6ImljbiIsImlkIjoiMTAxMjcwNDY4NlYxNTk4ODcifSwidmFtZi5hdXRoLnJlc291cmNlcyI6WyJeLiooLyk_c2l0ZVtzXT8vKGRmbi0pPzQ1My9wYXRpZW50W3NdPy8zNTE4NS9hcHBvaW50bWVudHMoLy4qKT8kIiwiXi4qKC8pP3BhdGllbnRbc10_L0VESVBJLzE2MDc2OTQ5MDMoLy4qKT8kIiwiXi4qKC8pP3BhdGllbnRbc10_LyhJQ04vKT8xMDEyNzA0Njg2VjE1OTg4NygvLiopPyQiXSwidmVyc2lvbiI6Mi44LCJmaXJzdE5hbWUiOiJWQS5nb3YgU2lnbnVwIChTUUEpIiwiYXVkIjoiYzdkNmUwZmM5YTM5IiwibmJmIjoxNjkyOTIxMTEzLCJzc3QiOjE2OTI5MjEyOTMsInZhbWYuYXV0aC5yb2xlcyI6WyJ2ZXRlcmFuIl0sInVzZXJUeXBlIjoib24tYmVoYWxmLW9mIiwiZXhwIjoyMDkyOTIyMTkzLCJpYXQiOjE2OTI5MjEyOTMsImp0aSI6IjM0NjNiOGI0LTNmOWYtNGU2Yi1iM2IyLTcwZTBhMDhjODkxOCJ9.Hbl4IWvV6zsPS9oeFAtzeCTMxPvlPkmJy11WzOLk4TV3-XEwn3c5rRz1ZISpOGiFsnmOq4faYpiLS8g3QCyjetJSbH9JU1QSXU9s6xGbBTGg1rmWzUyePUbvMukPsF5Ig-oqdTs_K58J3ylUOANJKv6DRd3PsYjlWvMqpyiNH63NCqmvN2RyhUO_Q4sRw-lA-sFhGBvuUeeiZL9kt9UeuwTvKJLR5eYhwB_aZI4XLoF3Cmlnje4p8hxaRMzGF6h_9WbA0j8M0GP1r5NkAoVqgmZ2Cs9WwTViOd7xKFLkdX67ZYRyvbjvoejrvkl85Vi2cWTAH7piCeQSRx3r_Dg-fw-53iu5IHC_0nhwhx-VdvSIoSGya_qRowzEzOaITQv5JxXZzgh2Cb5HdzcFBPb6k-MB_rSZh6htSpF9g64vzHGlJjOwa4zUQcab6QnIayJcg8OjF0JK5rtUe3_Vl3Y2_S-0RdogORNW61swjlG7UcZxUegn4Ac3XOxlHKEBUDCeZK_6nWzPmYJzUSPlVU_vQCnF04kCE34dlH3LGgpaT_s_aysyILl7J76hvl526muHx_3dyoliGgDB08LAJtXn56NeqrGzmnv_sli0V-spB4h6bnvMdqc1YSXARpoRiKms9l8SLspyWRikhreMzzon1ajUdXS0mEroxPPJZCq_s9c","token_type":"Bearer","expires_in":899}' recorded_at: Wed, 26 Oct 2022 18:30:02 GMT recorded_with: VCR 6.1.0 From b51b540321849c05f00f44e4a5b5fbb952b677ae Mon Sep 17 00:00:00 2001 From: John Bramley <20125855+bramleyjl@users.noreply.github.com> Date: Tue, 17 Dec 2024 15:55:05 -0700 Subject: [PATCH 7/7] spec & mock updates --- config/settings.yml | 1 - lib/map/security_token/configuration.rb | 2 +- lib/map/security_token/service.rb | 8 +- spec/lib/map/security_token/service_spec.rb | 18 +-- spec/lib/map/sign_up/service_spec.rb | 2 +- spec/requests/v0/map_services_spec.rb | 4 +- ...curity_token_service_200_invalid_token.yml | 141 ++++++++++++++++++ ...y_token_service_200_malformed_response.yml | 72 --------- .../security_token_service_200_response.yml | 71 ++++++++- .../map/sign_up_service_200_responses.yml | 2 +- 10 files changed, 230 insertions(+), 91 deletions(-) create mode 100644 spec/support/vcr_cassettes/map/security_token_service_200_invalid_token.yml delete mode 100644 spec/support/vcr_cassettes/map/security_token_service_200_malformed_response.yml diff --git a/config/settings.yml b/config/settings.yml index fdb86c04902..c8afe037810 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -33,7 +33,6 @@ map_services: oauth_url: https://veteran.apps-staging.va.gov client_cert_path: spec/fixtures/map/oauth.crt client_key_path: spec/fixtures/map/oauth.key - provider_jwks_path: /sts/oauth/v1/jwks sign_up_service_url: https://cerner.apps-staging.va.gov sign_up_service_provisioning_api_key: abcd1234 secure_token_service: diff --git a/lib/map/security_token/configuration.rb b/lib/map/security_token/configuration.rb index 203b32a05a8..5218996fbf8 100644 --- a/lib/map/security_token/configuration.rb +++ b/lib/map/security_token/configuration.rb @@ -35,7 +35,7 @@ def client_cert_path end def provider_jwks_path - Settings.map_services.provider_jwks_path + '/sts/oauth/v1/jwks' end def service_name diff --git a/lib/map/security_token/service.rb b/lib/map/security_token/service.rb index dc7f2cf12f5..5c899a1d29d 100644 --- a/lib/map/security_token/service.rb +++ b/lib/map/security_token/service.rb @@ -21,6 +21,10 @@ def token(application:, icn:, cache: true) Rails.logger.error("#{config.logging_prefix} token failed, parsing error", application:, icn:, context: e.message) raise e + rescue JWT::DecodeError => e + Rails.logger.error("#{config.logging_prefix} token failed, JWT decode error", application:, icn:, + context: e.message) + raise e rescue Common::Client::Errors::ClientError => e parse_and_raise_error(e, icn, application) rescue Common::Exceptions::GatewayTimeout => e @@ -63,9 +67,7 @@ def parse_response(response, application, icn) access_token: response_body['access_token'], expiration: Time.zone.now + response_body['expires_in'] } - rescue JWT::VerificationError => e - message = "#{config.logging_prefix} token failed, JWT verification error" - Rails.logger.error(message, application:, icn:) + rescue JWT::DecodeError => e raise e rescue => e message = "#{config.logging_prefix} token failed, response unknown" diff --git a/spec/lib/map/security_token/service_spec.rb b/spec/lib/map/security_token/service_spec.rb index 1ca9a7a6266..95a1cfe894d 100644 --- a/spec/lib/map/security_token/service_spec.rb +++ b/spec/lib/map/security_token/service_spec.rb @@ -127,16 +127,16 @@ end end - context 'when response is malformed', - vcr: { cassette_name: 'map/security_token_service_200_malformed_response' } do - let(:expected_error) { Common::Client::Errors::ParsingError } - let(:expected_error_message) { "unexpected token at 'Not valid JSON'" } - let(:expected_logger_message) { "#{log_prefix} token failed, parsing error" } - let(:expected_log_values) { { application:, icn:, context: expected_error_message } } - - it 'raises an gateway timeout error and creates a log' do + context 'when response is an invalid token', + vcr: { cassette_name: 'map/security_token_service_200_invalid_token' } do + let(:expected_error) { JWT::DecodeError } + let(:expected_error_context) { 'Signature verification failed' } + let(:expected_logger_message) { "#{log_prefix} token failed, JWT decode error" } + let(:expected_log_values) { { application:, icn:, context: expected_error_context } } + + it 'raises a JWT Decode error and creates a log' do expect(Rails.logger).to receive(:error).with(expected_logger_message, expected_log_values) - expect { subject }.to raise_exception(expected_error, expected_error_message) + expect { subject }.to raise_exception(expected_error, expected_error_context) end end diff --git a/spec/lib/map/sign_up/service_spec.rb b/spec/lib/map/sign_up/service_spec.rb index 4192942a627..7f49b69a4ec 100644 --- a/spec/lib/map/sign_up/service_spec.rb +++ b/spec/lib/map/sign_up/service_spec.rb @@ -126,7 +126,7 @@ let(:expected_log_message) { "#{log_prefix} agreements accept success, icn: #{icn}" } before do - Timecop.freeze(Time.zone.local(2023, 1, 1, 12, 0, 0)) + Timecop.freeze(Time.zone.local(2024, 9, 1, 12, 0, 0)) allow(Rails.logger).to receive(:info) end diff --git a/spec/requests/v0/map_services_spec.rb b/spec/requests/v0/map_services_spec.rb index 8836ff1258a..4198b4d2e57 100644 --- a/spec/requests/v0/map_services_spec.rb +++ b/spec/requests/v0/map_services_spec.rb @@ -93,8 +93,8 @@ end end - context 'when MAP STS client returns a token with an invalid duration', - vcr: { cassette_name: 'map/security_token_service_200_response_invalid_token' } do + context 'when MAP STS client returns an invalid token', + vcr: { cassette_name: 'map/security_token_service_200_invalid_token' } do it 'responds with error details in response body' do call_endpoint expect(JSON.parse(response.body)).to eq( diff --git a/spec/support/vcr_cassettes/map/security_token_service_200_invalid_token.yml b/spec/support/vcr_cassettes/map/security_token_service_200_invalid_token.yml new file mode 100644 index 00000000000..348bb3687b4 --- /dev/null +++ b/spec/support/vcr_cassettes/map/security_token_service_200_invalid_token.yml @@ -0,0 +1,141 @@ +--- +http_interactions: +- request: + method: post + uri: https://veteran.apps-staging.va.gov/sts/oauth/v1/token + body: + encoding: US-ASCII + string: grant_type=client_credentials&client_id=c7d6e0fc9a39&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=eyJhbGciOiJSUzUxMiJ9.eyJyb2xlIjoidmV0ZXJhbiIsInBhdGllbnRfaWQiOiJzb21lLWljbiIsInBhdGllbnRfaWRfdHlwZSI6ImljbiIsInN1YiI6ImM3ZDZlMGZjOWEzOSIsImp0aSI6IjIwODllOWFlLTZiNDctNGJkNy05NzNiLTczMzM4NjgzYTVkYiIsImlzcyI6ImM3ZDZlMGZjOWEzOSIsImF1ZCI6Imh0dHBzOi8vZ29vZ2xlLmNvbS9zdHMvb2F1dGgvdjEvdG9rZW4iLCJuYmYiOjE2OTI5MjE5NjcsImV4cCI6MTY5MjkyMjI2N30.VXzWaXBjk83TNA39VTApJQSG9inwyUioYouGXeqkEWicSP3oLb-CNFpkEgkMNccz6SpAlYIJ_KYKRFAA1rQv8Gp5LzIv_YM2WFJUYxpF02-fAhYzl6SkOLwD86Yto6a8JbFrNPL9uYxG1vmTZgl_vk2dmNFpnQ3gf8bXc2GOBAM2gc3tzNjv1M18dVtObX6zw7ZG7drxw7itzZnkDLTU9217XyOgSFQvA0czRiiRcfsXb6LIB7A1k7MpQy6KA3UDBQ7sbuXkaFZiJo2tSDG3PXScTHBtqmqejCt68906wiBf_ACeI4TQPH4ogoTrnfb9oprQyKp8xMlwwKYAMih12g + headers: + Accept: + - application/json + Content-Type: + - application/x-www-form-urlencoded + User-Agent: + - Vets.gov Agent + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Content-Type: + - application/json; charset=utf-8 + X-Frame-Options: + - allow-from https://nextgenid-mbetenantworkflow.azurewebsites.net + X-Xss-Protection: + - 1; mode=block + X-Content-Type-Options: + - nosniff + X-Download-Options: + - noopen + X-Permitted-Cross-Domain-Policies: + - none + Referrer-Policy: + - strict-origin-when-cross-origin + Content-Security-Policy: + - frame-ancestors https://nextgenid-mbetenantworkflow.azurewebsites.net + Etag: + - W/"dba68a519b00d7f452e79971a398650f" + X-Request-Id: + - 5b1d220c-4b01-4409-b9a5-367ab3c99ca9 + X-Runtime: + - '0.026178' + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Node: + - sandbox-core-02.idmeinc.net + Vary: + - Accept-Encoding + Expires: + - Wed, 26 Jul 2023 19:56:07 GMT + Cache-Control: + - max-age=0, no-cache, no-store + Pragma: + - no-cache + Date: + - Wed, 26 Jul 2023 19:56:07 GMT + Content-Length: + - '14658' + Connection: + - keep-alive + Server-Timing: + - ak_p; desc="1690401366974_1752320020_1303469004_11342_12901_31_-_-";dur=1 + - cdn-cache; desc=MISS + - edge; dur=68 + - origin; dur=46 + body: + encoding: UTF-8 + string: '{"access_token":"eyJhbGciOiJSUzUxMiJ9.eyJsYXN0TmFtZSI6Im9hdXRoLWNsaWVudCIsInN1YiI6ImM3ZDZlMGZjOWEzOSIsImF1dGhlbnRpY2F0ZWQiOnRydWUsImF1dGhlbnRpY2F0aW9uQXV0aG9yaXR5IjoiZ292LnZhLm1vYmlsZS5vYXV0aC52MSIsImlkVHlwZSI6Ik1PQklMRV9PQVVUSF9TVFNfQ0xJRU5UX0lEIiwiaXNzIjoiZ292LnZhLnZhbWYudXNlcnNlcnZpY2UudjIiLCJvbkJlaGFsZk9mIjp7ImlkVHlwZSI6ImljbiIsImlkIjoiMTAxMjcwNDY4NlYxNTk4ODcifSwidmFtZi5hdXRoLnJlc291cmNlcyI6WyJeLiooXC8pP3NpdGVbc10_XC8oZGZuLSk_NDUzXC9wYXRpZW50W3NdP1wvMzUxODVcL2FwcG9pbnRtZW50cyhcLy4qKT8kIiwiXi4qKFwvKT9wYXRpZW50W3NdP1wvRURJUElcLzE2MDc2OTQ5MDMoXC8uKik_JCIsIl4uKihcLyk_cGF0aWVudFtzXT9cLyhJQ05cLyk_MTAxMjcwNDY4NlYxNTk4ODcoXC8uKik_JCJdLCJ2ZXJzaW9uIjoyLjgsImZpcnN0TmFtZSI6IlZBLmdvdiBTaWdudXAgKFNRQSkiLCJhdWQiOiJjN2Q2ZTBmYzlhMzkiLCJuYmYiOjE2OTI5MjExMTMsInNzdCI6MTY5MjkyMTI5MywidmFtZi5hdXRoLnJvbGVzIjpbInZldGVyYW4iXSwidXNlclR5cGUiOiJvbi1iZWhhbGYtb2YiLCJleHAiOjE2OTI5MjIxOTMsImlhdCI6MTY5MjkyMTI5MywianRpIjoiMzQ2M2I4YjQtM2Y5Zi00ZTZiLWIzYjItNzBlMGEwOGM4OTE4In0.LXAxWbzCmVZEothmkV3CFi5Jitx8MYnmkPSIqOkWghOz2wZJV7SX96bBhZ3zK5xUYlxwQ_ElwKU3otb47IeWK3XflbW1K1m8HbZ5qtKgfofv4sk0xM7UEafRQdmLGQOX0ClqbmMrNss12z5Ay0BSBpltoBGekKyRcwRerhP35o4d0uHKDY8JanhljylZupfO8e5Kpx8R0UfL1rXRXjhAWTbf23oJOB8onvJ_RZz1YHXQU-M34-faj_iHKrms3t9h7n3fhJKYciYOAfxN2feeOpFJ95Zt-mJGARUY3ryeIXFm5HJjL1KTjZ1eB9NmX7H2ST3uqax0PY5biYiiwX1a2g","token_type":"Bearer","expires_in":899}' + recorded_at: Wed, 26 Oct 2022 18:30:02 GMT +- request: + method: get + uri: https://veteran.apps-staging.va.gov/sts/oauth/v1/jwks + body: + encoding: US-ASCII + string: '' + headers: + Accept: + - application/json + Content-Type: + - application/x-www-form-urlencoded + User-Agent: + - Vets.gov Agent + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Content-Type: + - application/json; charset=utf-8 + X-Frame-Options: + - allow-from https://nextgenid-mbetenantworkflow.azurewebsites.net + X-Xss-Protection: + - 1; mode=block + X-Content-Type-Options: + - nosniff + X-Download-Options: + - noopen + X-Permitted-Cross-Domain-Policies: + - none + Referrer-Policy: + - strict-origin-when-cross-origin + Content-Security-Policy: + - frame-ancestors https://nextgenid-mbetenantworkflow.azurewebsites.net + Etag: + - W/"dba68a519b00d7f452e79971a398650f" + X-Request-Id: + - 5b1d220c-4b01-4409-b9a5-367ab3c99ca9 + X-Runtime: + - '0.026178' + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Node: + - sandbox-core-02.idmeinc.net + Vary: + - Accept-Encoding + Expires: + - Wed, 26 Jul 2023 19:56:07 GMT + Cache-Control: + - max-age=0, no-cache, no-store + Pragma: + - no-cache + Date: + - Wed, 26 Jul 2023 19:56:07 GMT + Content-Length: + - '14658' + Connection: + - keep-alive + Server-Timing: + - ak_p; desc="1690401366974_1752320020_1303469004_11342_12901_31_-_-";dur=1 + - cdn-cache; desc=MISS + - edge; dur=68 + - origin; dur=46 + body: + encoding: UTF-8 + string: '{"keys":[{"kty":"RSA","e":"AQAB","use":"sig","kid":"c9233bd7a62406b325c3cbf9778ea1ec75fa6de587640ee6d522e1bda2251277","alg":"RS512","n":"rGRLjxGb2ygtXWEEC99h5Z__PrAAqf0_wXQcFDnbV1bCp2rfv1xprPS-Mhi_mLh4YVBVKfD5vz0X9eHq1ieua_prgIgloT4doOzphkPTVoALQcm7HmBEWOs3r_nOIZMyOomPb-i4EqNITqD-qEdxGce5-GuopT1BotKzwtX5m7YlqviLFvyCQIRxr1C8GspAjyrODZVTTiKN0nyQKO3EUQZ2ietC52sbnSlnFOHbIpRP1mBrRvkELYIk8gfInMNvSk98SeWd2dDGe48OKNAzR2zGWYwIvxChBAoxahQ1Rh89WF1zKWIRTxYTuBJP3owBJdcfDcvTxovW5y6ciL0KyJKkZgyRJuBvIt8P9tEus8ef9s_3dRnKJi46uRolre5snXWIAAf-fUZvHdnwPLfANgqpNauVPwjtC_MGvbXYALdyCpIUmuRhWX_OHWYl7PTjllMezjVNylSK-2QVc6M7U3OXt00Q8poRKEUquowNPgbNaQnBzOtOEnpqCNIl0_86Qf8QLoSbdF4B0Yr2LJPraPsFxT3xdbcg9bS8vvGWJ2a2KmLqDKmpm6e9Cr3QZ-2-rUBn4KURjnV2KWQM-6tYwUTV0o467OaCNwkUSOqaPUuMbRHR7L5YTuA8BkJsPv_6pZe3VD74N9kbSMlt7RC2Qo2FCyxRwUtdSzTjheJwrvs"}]}' + recorded_at: Wed, 26 Oct 2022 18:30:02 GMT +recorded_with: VCR 6.1.0 diff --git a/spec/support/vcr_cassettes/map/security_token_service_200_malformed_response.yml b/spec/support/vcr_cassettes/map/security_token_service_200_malformed_response.yml deleted file mode 100644 index 5f10093e3df..00000000000 --- a/spec/support/vcr_cassettes/map/security_token_service_200_malformed_response.yml +++ /dev/null @@ -1,72 +0,0 @@ ---- -http_interactions: -- request: - method: post - uri: https://veteran.apps-staging.va.gov/sts/oauth/v1/token - body: - encoding: US-ASCII - string: grant_type=client_credentials&client_id=c7d6e0fc9a39&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=eyJhbGciOiJSUzUxMiJ9.eyJyb2xlIjoidmV0ZXJhbiIsInBhdGllbnRfaWQiOiJzb21lLWljbiIsInBhdGllbnRfaWRfdHlwZSI6ImljbiIsInN1YiI6ImM3ZDZlMGZjOWEzOSIsImp0aSI6IjIwODllOWFlLTZiNDctNGJkNy05NzNiLTczMzM4NjgzYTVkYiIsImlzcyI6ImM3ZDZlMGZjOWEzOSIsImF1ZCI6Imh0dHBzOi8vZ29vZ2xlLmNvbS9zdHMvb2F1dGgvdjEvdG9rZW4iLCJuYmYiOjE2OTI5MjE5NjcsImV4cCI6MTY5MjkyMjI2N30.VXzWaXBjk83TNA39VTApJQSG9inwyUioYouGXeqkEWicSP3oLb-CNFpkEgkMNccz6SpAlYIJ_KYKRFAA1rQv8Gp5LzIv_YM2WFJUYxpF02-fAhYzl6SkOLwD86Yto6a8JbFrNPL9uYxG1vmTZgl_vk2dmNFpnQ3gf8bXc2GOBAM2gc3tzNjv1M18dVtObX6zw7ZG7drxw7itzZnkDLTU9217XyOgSFQvA0czRiiRcfsXb6LIB7A1k7MpQy6KA3UDBQ7sbuXkaFZiJo2tSDG3PXScTHBtqmqejCt68906wiBf_ACeI4TQPH4ogoTrnfb9oprQyKp8xMlwwKYAMih12g - headers: - Accept: - - application/json - Content-Type: - - application/x-www-form-urlencoded - User-Agent: - - Vets.gov Agent - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - response: - status: - code: 200 - message: OK - headers: - Content-Type: - - application/json; charset=utf-8 - X-Frame-Options: - - allow-from https://nextgenid-mbetenantworkflow.azurewebsites.net - X-Xss-Protection: - - 1; mode=block - X-Content-Type-Options: - - nosniff - X-Download-Options: - - noopen - X-Permitted-Cross-Domain-Policies: - - none - Referrer-Policy: - - strict-origin-when-cross-origin - Content-Security-Policy: - - frame-ancestors https://nextgenid-mbetenantworkflow.azurewebsites.net - Etag: - - W/"dba68a519b00d7f452e79971a398650f" - X-Request-Id: - - 5b1d220c-4b01-4409-b9a5-367ab3c99ca9 - X-Runtime: - - '0.026178' - Strict-Transport-Security: - - max-age=63072000; includeSubDomains - X-Node: - - sandbox-core-02.idmeinc.net - Vary: - - Accept-Encoding - Expires: - - Wed, 26 Jul 2023 19:56:07 GMT - Cache-Control: - - max-age=0, no-cache, no-store - Pragma: - - no-cache - Date: - - Wed, 26 Jul 2023 19:56:07 GMT - Content-Length: - - '14658' - Connection: - - keep-alive - Server-Timing: - - ak_p; desc="1690401366974_1752320020_1303469004_11342_12901_31_-_-";dur=1 - - cdn-cache; desc=MISS - - edge; dur=68 - - origin; dur=46 - body: - encoding: UTF-8 - string: 'Not valid JSON' - recorded_at: Wed, 26 Oct 2022 18:30:02 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/support/vcr_cassettes/map/security_token_service_200_response.yml b/spec/support/vcr_cassettes/map/security_token_service_200_response.yml index 4b694a324b9..417e0d3f6a7 100644 --- a/spec/support/vcr_cassettes/map/security_token_service_200_response.yml +++ b/spec/support/vcr_cassettes/map/security_token_service_200_response.yml @@ -67,6 +67,75 @@ http_interactions: - origin; dur=46 body: encoding: UTF-8 - string: {"access_token":"eyJhbGciOiJSUzUxMiJ9.eyJsYXN0TmFtZSI6Im9hdXRoLWNsaWVudCIsInN1YiI6ImM3ZDZlMGZjOWEzOSIsImF1dGhlbnRpY2F0ZWQiOnRydWUsImF1dGhlbnRpY2F0aW9uQXV0aG9yaXR5IjoiZ292LnZhLm1vYmlsZS5vYXV0aC52MSIsImlkVHlwZSI6Ik1PQklMRV9PQVVUSF9TVFNfQ0xJRU5UX0lEIiwiaXNzIjoiZ292LnZhLnZhbWYudXNlcnNlcnZpY2UudjIiLCJvbkJlaGFsZk9mIjp7ImlkVHlwZSI6ImljbiIsImlkIjoiMTAxMjcwNDY4NlYxNTk4ODcifSwidmFtZi5hdXRoLnJlc291cmNlcyI6WyJeLiooLyk_c2l0ZVtzXT8vKGRmbi0pPzQ1My9wYXRpZW50W3NdPy8zNTE4NS9hcHBvaW50bWVudHMoLy4qKT8kIiwiXi4qKC8pP3BhdGllbnRbc10_L0VESVBJLzE2MDc2OTQ5MDMoLy4qKT8kIiwiXi4qKC8pP3BhdGllbnRbc10_LyhJQ04vKT8xMDEyNzA0Njg2VjE1OTg4NygvLiopPyQiXSwidmVyc2lvbiI6Mi44LCJmaXJzdE5hbWUiOiJWQS5nb3YgU2lnbnVwIChTUUEpIiwiYXVkIjoiYzdkNmUwZmM5YTM5IiwibmJmIjoxNjkyOTIxMTEzLCJzc3QiOjE2OTI5MjEyOTMsInZhbWYuYXV0aC5yb2xlcyI6WyJ2ZXRlcmFuIl0sInVzZXJUeXBlIjoib24tYmVoYWxmLW9mIiwiZXhwIjoyMDkyOTIyMTkzLCJpYXQiOjE2OTI5MjEyOTMsImp0aSI6IjM0NjNiOGI0LTNmOWYtNGU2Yi1iM2IyLTcwZTBhMDhjODkxOCJ9.Hbl4IWvV6zsPS9oeFAtzeCTMxPvlPkmJy11WzOLk4TV3-XEwn3c5rRz1ZISpOGiFsnmOq4faYpiLS8g3QCyjetJSbH9JU1QSXU9s6xGbBTGg1rmWzUyePUbvMukPsF5Ig-oqdTs_K58J3ylUOANJKv6DRd3PsYjlWvMqpyiNH63NCqmvN2RyhUO_Q4sRw-lA-sFhGBvuUeeiZL9kt9UeuwTvKJLR5eYhwB_aZI4XLoF3Cmlnje4p8hxaRMzGF6h_9WbA0j8M0GP1r5NkAoVqgmZ2Cs9WwTViOd7xKFLkdX67ZYRyvbjvoejrvkl85Vi2cWTAH7piCeQSRx3r_Dg-fw-53iu5IHC_0nhwhx-VdvSIoSGya_qRowzEzOaITQv5JxXZzgh2Cb5HdzcFBPb6k-MB_rSZh6htSpF9g64vzHGlJjOwa4zUQcab6QnIayJcg8OjF0JK5rtUe3_Vl3Y2_S-0RdogORNW61swjlG7UcZxUegn4Ac3XOxlHKEBUDCeZK_6nWzPmYJzUSPlVU_vQCnF04kCE34dlH3LGgpaT_s_aysyILl7J76hvl526muHx_3dyoliGgDB08LAJtXn56NeqrGzmnv_sli0V-spB4h6bnvMdqc1YSXARpoRiKms9l8SLspyWRikhreMzzon1ajUdXS0mEroxPPJZCq_s9c","token_type":"Bearer","expires_in":899}' + string: '{"access_token":"eyJhbGciOiJSUzUxMiJ9.eyJsYXN0TmFtZSI6Im9hdXRoLWNsaWVudCIsInN1YiI6ImM3ZDZlMGZjOWEzOSIsImF1dGhlbnRpY2F0ZWQiOnRydWUsImF1dGhlbnRpY2F0aW9uQXV0aG9yaXR5IjoiZ292LnZhLm1vYmlsZS5vYXV0aC52MSIsImlkVHlwZSI6Ik1PQklMRV9PQVVUSF9TVFNfQ0xJRU5UX0lEIiwiaXNzIjoiZ292LnZhLnZhbWYudXNlcnNlcnZpY2UudjIiLCJvbkJlaGFsZk9mIjp7ImlkVHlwZSI6ImljbiIsImlkIjoiMTAxMjcwNDY4NlYxNTk4ODcifSwidmFtZi5hdXRoLnJlc291cmNlcyI6WyJeLiooLyk_c2l0ZVtzXT8vKGRmbi0pPzQ1My9wYXRpZW50W3NdPy8zNTE4NS9hcHBvaW50bWVudHMoLy4qKT8kIiwiXi4qKC8pP3BhdGllbnRbc10_L0VESVBJLzE2MDc2OTQ5MDMoLy4qKT8kIiwiXi4qKC8pP3BhdGllbnRbc10_LyhJQ04vKT8xMDEyNzA0Njg2VjE1OTg4NygvLiopPyQiXSwidmVyc2lvbiI6Mi44LCJmaXJzdE5hbWUiOiJWQS5nb3YgU2lnbnVwIChTUUEpIiwiYXVkIjoiYzdkNmUwZmM5YTM5IiwibmJmIjoxNjkyOTIxMTEzLCJzc3QiOjE2OTI5MjEyOTMsInZhbWYuYXV0aC5yb2xlcyI6WyJ2ZXRlcmFuIl0sInVzZXJUeXBlIjoib24tYmVoYWxmLW9mIiwiZXhwIjoyMDkyOTIyMTkzLCJpYXQiOjE2OTI5MjEyOTMsImp0aSI6IjM0NjNiOGI0LTNmOWYtNGU2Yi1iM2IyLTcwZTBhMDhjODkxOCJ9.Hbl4IWvV6zsPS9oeFAtzeCTMxPvlPkmJy11WzOLk4TV3-XEwn3c5rRz1ZISpOGiFsnmOq4faYpiLS8g3QCyjetJSbH9JU1QSXU9s6xGbBTGg1rmWzUyePUbvMukPsF5Ig-oqdTs_K58J3ylUOANJKv6DRd3PsYjlWvMqpyiNH63NCqmvN2RyhUO_Q4sRw-lA-sFhGBvuUeeiZL9kt9UeuwTvKJLR5eYhwB_aZI4XLoF3Cmlnje4p8hxaRMzGF6h_9WbA0j8M0GP1r5NkAoVqgmZ2Cs9WwTViOd7xKFLkdX67ZYRyvbjvoejrvkl85Vi2cWTAH7piCeQSRx3r_Dg-fw-53iu5IHC_0nhwhx-VdvSIoSGya_qRowzEzOaITQv5JxXZzgh2Cb5HdzcFBPb6k-MB_rSZh6htSpF9g64vzHGlJjOwa4zUQcab6QnIayJcg8OjF0JK5rtUe3_Vl3Y2_S-0RdogORNW61swjlG7UcZxUegn4Ac3XOxlHKEBUDCeZK_6nWzPmYJzUSPlVU_vQCnF04kCE34dlH3LGgpaT_s_aysyILl7J76hvl526muHx_3dyoliGgDB08LAJtXn56NeqrGzmnv_sli0V-spB4h6bnvMdqc1YSXARpoRiKms9l8SLspyWRikhreMzzon1ajUdXS0mEroxPPJZCq_s9c","token_type":"Bearer","expires_in":899}' + recorded_at: Wed, 26 Oct 2022 18:30:02 GMT +- request: + method: get + uri: https://veteran.apps-staging.va.gov/sts/oauth/v1/jwks + body: + encoding: US-ASCII + string: '' + headers: + Accept: + - application/json + Content-Type: + - application/x-www-form-urlencoded + User-Agent: + - Vets.gov Agent + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Content-Type: + - application/json; charset=utf-8 + X-Frame-Options: + - allow-from https://nextgenid-mbetenantworkflow.azurewebsites.net + X-Xss-Protection: + - 1; mode=block + X-Content-Type-Options: + - nosniff + X-Download-Options: + - noopen + X-Permitted-Cross-Domain-Policies: + - none + Referrer-Policy: + - strict-origin-when-cross-origin + Content-Security-Policy: + - frame-ancestors https://nextgenid-mbetenantworkflow.azurewebsites.net + Etag: + - W/"dba68a519b00d7f452e79971a398650f" + X-Request-Id: + - 5b1d220c-4b01-4409-b9a5-367ab3c99ca9 + X-Runtime: + - '0.026178' + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Node: + - sandbox-core-02.idmeinc.net + Vary: + - Accept-Encoding + Expires: + - Wed, 26 Jul 2023 19:56:07 GMT + Cache-Control: + - max-age=0, no-cache, no-store + Pragma: + - no-cache + Date: + - Wed, 26 Jul 2023 19:56:07 GMT + Content-Length: + - '14658' + Connection: + - keep-alive + Server-Timing: + - ak_p; desc="1690401366974_1752320020_1303469004_11342_12901_31_-_-";dur=1 + - cdn-cache; desc=MISS + - edge; dur=68 + - origin; dur=46 + body: + encoding: UTF-8 + string: '{"keys":[{"kty":"RSA","e":"AQAB","use":"sig","kid":"c9233bd7a62406b325c3cbf9778ea1ec75fa6de587640ee6d522e1bda2251277","alg":"RS512","n":"rGRLjxGb2ygtXWEEC99h5Z__PrAAqf0_wXQcFDnbV1bCp2rfv1xprPS-Mhi_mLh4YVBVKfD5vz0X9eHq1ieua_prgIgloT4doOzphkPTVoALQcm7HmBEWOs3r_nOIZMyOomPb-i4EqNITqD-qEdxGce5-GuopT1BotKzwtX5m7YlqviLFvyCQIRxr1C8GspAjyrODZVTTiKN0nyQKO3EUQZ2ietC52sbnSlnFOHbIpRP1mBrRvkELYIk8gfInMNvSk98SeWd2dDGe48OKNAzR2zGWYwIvxChBAoxahQ1Rh89WF1zKWIRTxYTuBJP3owBJdcfDcvTxovW5y6ciL0KyJKkZgyRJuBvIt8P9tEus8ef9s_3dRnKJi46uRolre5snXWIAAf-fUZvHdnwPLfANgqpNauVPwjtC_MGvbXYALdyCpIUmuRhWX_OHWYl7PTjllMezjVNylSK-2QVc6M7U3OXt00Q8poRKEUquowNPgbNaQnBzOtOEnpqCNIl0_86Qf8QLoSbdF4B0Yr2LJPraPsFxT3xdbcg9bS8vvGWJ2a2KmLqDKmpm6e9Cr3QZ-2-rUBn4KURjnV2KWQM-6tYwUTV0o467OaCNwkUSOqaPUuMbRHR7L5YTuA8BkJsPv_6pZe3VD74N9kbSMlt7RC2Qo2FCyxRwUtdSzTjheJwrvs"}]}' recorded_at: Wed, 26 Oct 2022 18:30:02 GMT recorded_with: VCR 6.1.0 diff --git a/spec/support/vcr_cassettes/map/sign_up_service_200_responses.yml b/spec/support/vcr_cassettes/map/sign_up_service_200_responses.yml index 3c0ea903a8f..33abefd9213 100644 --- a/spec/support/vcr_cassettes/map/sign_up_service_200_responses.yml +++ b/spec/support/vcr_cassettes/map/sign_up_service_200_responses.yml @@ -74,7 +74,7 @@ http_interactions: uri: https://cerner.apps-staging.va.gov/signup/v1/patients/10101V964144/agreements body: encoding: US-ASCII - string: '{"responseDate":"2023-01-01T12:00:00.000Z","icn":"10101V964144","signatureName":"some-signature-name","version":3,"legalDisplayVersion":1.0}' + string: '{"responseDate":"2024-09-01T12:00:00.000Z","icn":"10101V964144","signatureName":"some-signature-name","version":3,"legalDisplayVersion":1.0}' headers: Accept: - application/json