From bdd7a81f6ad0297f0e4e3974aad076d4f284cd54 Mon Sep 17 00:00:00 2001 From: Tamir Zheleznyak Date: Tue, 3 Aug 2021 21:02:36 +0300 Subject: [PATCH 1/5] ONYX-11330: Fix cache of signing key --- .../signing_key/fetch_cached_signing_key.rb | 27 ++ .../signing_key/fetch_jwks_uri_signing_key.rb | 6 +- .../fetch_provider_uri_signing_key.rb | 6 +- .../fetch_signing_key_interface.rb | 2 +- .../validate_and_decode_token.rb | 27 +- .../configuration_jwt_generic_vendor.rb | 39 +-- app/domain/logs.rb | 12 + app/domain/util/concurrency_limited_cache.rb | 27 +- app/domain/util/rate_limited_cache.rb | 30 +- .../features/authn_jwt.feature | 9 +- .../authn_jwt_check_standard_claims.feature | 48 ++-- .../features/authn_jwt_configuration.feature | 50 ++-- ...n_jwt_fetch_identity_decoded_token.feature | 24 +- .../authn_jwt_fetch_identity_from_url.feature | 20 +- .../authn_jwt_fetch_signing_key.feature | 256 ++++++------------ .../authn_jwt_input_validation.feature | 20 +- .../features/authn_jwt_security.feature | 2 - .../features/authn_jwt_token_schema.feature | 54 ++-- .../authn_jwt_validate_and_decode.feature | 2 - .../authn_jwt_validate_restrictions.feature | 26 +- .../step_definitions/jwt_jwks_steps.rb | 9 + 21 files changed, 337 insertions(+), 359 deletions(-) create mode 100644 app/domain/authentication/authn_jwt/signing_key/fetch_cached_signing_key.rb diff --git a/app/domain/authentication/authn_jwt/signing_key/fetch_cached_signing_key.rb b/app/domain/authentication/authn_jwt/signing_key/fetch_cached_signing_key.rb new file mode 100644 index 0000000000..2d916585aa --- /dev/null +++ b/app/domain/authentication/authn_jwt/signing_key/fetch_cached_signing_key.rb @@ -0,0 +1,27 @@ +module Authentication + module AuthnJwt + module SigningKey + # FetchCachedSigningKey is a wrapper of FetchSigningKeyInterface interface, + # in order to be able to store the signing key in our cache mechanism. If signing_key_interface don't have + # fetch_signing_key it is extreme case that error need to be raised so it can be investigated so reek will ignore + # this. + # :reek:InstanceVariableAssumption + class FetchCachedSigningKey + def initialize(logger: Rails.logger) + @logger = logger + end + + def call(signing_key_interface:) + @signing_key_interface = signing_key_interface + fetch_signing_key + end + + private + + def fetch_signing_key + @signing_key_interface.fetch_signing_key + end + end + end + end +end diff --git a/app/domain/authentication/authn_jwt/signing_key/fetch_jwks_uri_signing_key.rb b/app/domain/authentication/authn_jwt/signing_key/fetch_jwks_uri_signing_key.rb index 350469715e..2d67827516 100644 --- a/app/domain/authentication/authn_jwt/signing_key/fetch_jwks_uri_signing_key.rb +++ b/app/domain/authentication/authn_jwt/signing_key/fetch_jwks_uri_signing_key.rb @@ -31,11 +31,15 @@ def valid_configuration? @valid_configuration = jwks_uri_resource_exists? end - def call + def fetch_signing_key fetch_jwks_uri fetch_jwks_keys end + def signing_key_uri + jwks_uri + end + private def jwks_uri_resource_exists? diff --git a/app/domain/authentication/authn_jwt/signing_key/fetch_provider_uri_signing_key.rb b/app/domain/authentication/authn_jwt/signing_key/fetch_provider_uri_signing_key.rb index 65d3faec84..6b61b7534c 100644 --- a/app/domain/authentication/authn_jwt/signing_key/fetch_provider_uri_signing_key.rb +++ b/app/domain/authentication/authn_jwt/signing_key/fetch_provider_uri_signing_key.rb @@ -25,11 +25,15 @@ def valid_configuration? @valid_configuration = provider_uri_resource_exists? end - def call + def fetch_signing_key discover_provider fetch_provider_keys end + def signing_key_uri + provider_uri + end + private def provider_uri_resource_exists? diff --git a/app/domain/authentication/authn_jwt/signing_key/fetch_signing_key_interface.rb b/app/domain/authentication/authn_jwt/signing_key/fetch_signing_key_interface.rb index 92e3ce4cd8..95956de192 100644 --- a/app/domain/authentication/authn_jwt/signing_key/fetch_signing_key_interface.rb +++ b/app/domain/authentication/authn_jwt/signing_key/fetch_signing_key_interface.rb @@ -2,7 +2,7 @@ module Authentication module AuthnJwt module SigningKey class FetchSigningKeyInterface - def call; end + def fetch_signing_key; end def valid_configuration?; end end diff --git a/app/domain/authentication/authn_jwt/validate_and_decode/validate_and_decode_token.rb b/app/domain/authentication/authn_jwt/validate_and_decode/validate_and_decode_token.rb index 614448a55b..b177a36072 100644 --- a/app/domain/authentication/authn_jwt/validate_and_decode/validate_and_decode_token.rb +++ b/app/domain/authentication/authn_jwt/validate_and_decode/validate_and_decode_token.rb @@ -7,12 +7,23 @@ module ValidateAndDecode # for the 2nd validation ValidateAndDecodeToken ||= CommandClass.new( dependencies: { + fetch_signing_key_from_cache: ::Util::ConcurrencyLimitedCache.new( + ::Util::RateLimitedCache.new( + ::Authentication::AuthnJwt::SigningKey::FetchCachedSigningKey.new, + refreshes_per_interval: CACHE_REFRESHES_PER_INTERVAL, + rate_limit_interval: CACHE_RATE_LIMIT_INTERVAL, + logger: Rails.logger + ), + max_concurrent_requests: CACHE_MAX_CONCURRENT_REQUESTS, + logger: Rails.logger + ), verify_and_decode_token: ::Authentication::Jwt::VerifyAndDecodeToken.new, fetch_jwt_claims_to_validate: ::Authentication::AuthnJwt::ValidateAndDecode::FetchJwtClaimsToValidate.new, get_verification_option_by_jwt_claim: ::Authentication::AuthnJwt::ValidateAndDecode::GetVerificationOptionByJwtClaim.new, + signing_key_interface_factory: ::Authentication::AuthnJwt::SigningKey::CreateSigningKeyFactory.new, logger: Rails.logger }, - inputs: %i[authentication_parameters fetch_signing_key] + inputs: %i[authentication_parameters] ) do extend(Forwardable) def_delegators(:@authentication_parameters, :jwt_token) @@ -20,6 +31,7 @@ module ValidateAndDecode def call @logger.debug(LogMessages::Authentication::AuthnJwt::ValidatingToken.new) validate_token_exists + fetch_signing_key_interface fetch_signing_key validate_signature fetch_jwt_claims_to_validate @@ -31,12 +43,23 @@ def call private + # Don't do memoization here because otherwise interface won't change between different requests + def fetch_signing_key_interface + @signing_key_interface = @signing_key_interface_factory.call( + authentication_parameters: @authentication_parameters + ) + end + def validate_token_exists raise Errors::Authentication::AuthnJwt::MissingToken if jwt_token.blank? end def fetch_signing_key(force_read: false) - @jwks = @fetch_signing_key.call(refresh: force_read) + @jwks = @fetch_signing_key_from_cache.call( + refresh: force_read, + cache_key: @signing_key_interface.signing_key_uri, + signing_key_interface: @signing_key_interface + ) @logger.debug(LogMessages::Authentication::AuthnJwt::SigningKeysFetchedFromCache.new) end diff --git a/app/domain/authentication/authn_jwt/vendor_configurations/configuration_jwt_generic_vendor.rb b/app/domain/authentication/authn_jwt/vendor_configurations/configuration_jwt_generic_vendor.rb index 67fcdeca7b..b75e2b547d 100644 --- a/app/domain/authentication/authn_jwt/vendor_configurations/configuration_jwt_generic_vendor.rb +++ b/app/domain/authentication/authn_jwt/vendor_configurations/configuration_jwt_generic_vendor.rb @@ -10,22 +10,22 @@ def initialize( logger: Rails.logger, authentication_parameters_class: Authentication::AuthnJwt::AuthenticationParameters, restriction_validator_class: Authentication::AuthnJwt::RestrictionValidation::ValidateRestrictionsOneToOne, - validate_and_decode_token_class: Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken, validate_resource_restrictions_class: Authentication::ResourceRestrictions::ValidateResourceRestrictions, extract_token_from_credentials: Authentication::AuthnJwt::InputValidation::ExtractTokenFromCredentials.new, create_identity_provider: Authentication::AuthnJwt::IdentityProviders::CreateIdentityProvider.new, create_constraints: Authentication::AuthnJwt::RestrictionValidation::CreateConstrains.new, - fetch_mapping_claims: Authentication::AuthnJwt::RestrictionValidation::FetchMappingClaims.new + fetch_mapping_claims: Authentication::AuthnJwt::RestrictionValidation::FetchMappingClaims.new, + validate_and_decode_token: Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new ) @logger = logger @authentication_parameters_class = authentication_parameters_class @restriction_validator_class = restriction_validator_class - @validate_and_decode_token_class = validate_and_decode_token_class @validate_resource_restrictions_class = validate_resource_restrictions_class @extract_token_from_credentials = extract_token_from_credentials @create_identity_provider = create_identity_provider @create_constraints = create_constraints @fetch_mapping_claims = fetch_mapping_claims + @validate_and_decode_token = validate_and_decode_token @logger.debug(LogMessages::Authentication::AuthnJwt::CreatingAuthenticationParametersObject.new) @authentication_parameters = @authentication_parameters_class.new( @@ -55,9 +55,8 @@ def validate_restrictions end def validate_and_decode_token - @authentication_parameters.decoded_token = validate_and_decode_token_instance.call( - authentication_parameters: @authentication_parameters, - fetch_signing_key: fetch_signing_key + @authentication_parameters.decoded_token = @validate_and_decode_token.call( + authentication_parameters: @authentication_parameters ) end @@ -83,27 +82,9 @@ def identity_provider ) end - def validate_and_decode_token_instance - return @validate_and_decode_token_instance if @validate_and_decode_token_instance - - @logger.debug(LogMessages::Authentication::AuthnJwt::CreateValidateAndDecodeTokenInstance.new) - @validate_and_decode_token_instance = @validate_and_decode_token_class.new( - fetch_jwt_claims_to_validate: fetch_jwt_claims_to_validate - ) - @logger.debug(LogMessages::Authentication::AuthnJwt::CreatedValidateAndDecodeTokenInstance.new) - @validate_and_decode_token_instance - end - - def fetch_signing_key - @fetch_signing_key ||= ::Util::ConcurrencyLimitedCache.new( - ::Util::RateLimitedCache.new( - fetch_signing_key_interface, - refreshes_per_interval: CACHE_REFRESHES_PER_INTERVAL, - rate_limit_interval: CACHE_RATE_LIMIT_INTERVAL, - logger: @logger - ), - max_concurrent_requests: CACHE_MAX_CONCURRENT_REQUESTS, - logger: @logger + def fetch_singing_key_interface + @fetch_singing_key_interface ||= create_signing_key_interface.call( + authentication_parameters: @authentication_parameters ) end @@ -124,10 +105,6 @@ def create_signing_key_interface @create_signing_key_interface ||= Authentication::AuthnJwt::SigningKey::CreateSigningKeyFactory.new end - def fetch_jwt_claims_to_validate - @fetch_jwt_claims_to_validate ||= ::Authentication::AuthnJwt::ValidateAndDecode::FetchJwtClaimsToValidate.new - end - def restrictions_from_annotations @restrictions_from_annotations ||= Authentication::ResourceRestrictions::GetServiceSpecificRestrictionFromAnnotation.new end diff --git a/app/domain/logs.rb b/app/domain/logs.rb index 697dc038f7..02b1cb4d53 100644 --- a/app/domain/logs.rb +++ b/app/domain/logs.rb @@ -712,6 +712,8 @@ module AuthnJwt end end + # This are log messages so its okay there are many + # :reek:TooManyConstants module Util RateLimitedCacheUpdated = ::Util::TrackableLogMessageClass.new( @@ -740,5 +742,15 @@ module Util code: "CONJ00023D" ) + ConcurrencyLimitedCacheKeyRetrieved = ::Util::TrackableLogMessageClass.new( + msg: "ConcurrencyLimitedCache retrieved cache key : '{0-cache-key}'", + code: "CONJ00024D" + ) + + RateLimitedCacheKeyRetrieved = ::Util::TrackableLogMessageClass.new( + msg: "RateLimitedCache Retrieved cache key : '{0-cache-key}'", + code: "CONJ00025D" + ) + end end diff --git a/app/domain/util/concurrency_limited_cache.rb b/app/domain/util/concurrency_limited_cache.rb index 6d68c7632d..ffc2676323 100644 --- a/app/domain/util/concurrency_limited_cache.rb +++ b/app/domain/util/concurrency_limited_cache.rb @@ -20,15 +20,20 @@ def initialize( # This method is passed exactly the same named arguments you'd pass to the # callable object, but you can optionally include the `refresh: true` to # force recalculation. + # + # In this case we should call @cache[cache_key] because setting it to variable requires treatment of case cache_key + # not in case before the flow runs and it can cause unexpected behaviour so reek will ignore this. + # reek:DuplicateMethodCall def call(**args) + cache_key = cached_key(args) @concurrency_mutex.synchronize do if @concurrent_requests >= @max_concurrent_requests @logger.debug( LogMessages::Util::ConcurrencyLimitedCacheReached.new(@max_concurrent_requests) ) - raise Errors::Util::ConcurrencyLimitReachedBeforeCacheInitialization unless @cache.key?(args) + raise Errors::Util::ConcurrencyLimitReachedBeforeCacheInitialization unless @cache.key?(cache_key) - return @cache[args] + return @cache[cache_key] end @concurrent_requests += 1 @@ -40,15 +45,15 @@ def call(**args) end @semaphore.synchronize do - recalculate(args) - @cache[args] + recalculate(args, cache_key) + @cache[cache_key] end end private - def recalculate(args) - @cache[args] = @target.call(**args) + def recalculate(args, cache_key) + @cache[cache_key] = @target.call(**args) @logger.debug(LogMessages::Util::ConcurrencyLimitedCacheUpdated.new) decrease_concurrent_requests rescue => e @@ -66,5 +71,15 @@ def decrease_concurrent_requests ) end end + + def cached_key(args) + cache_key = args.key?(:cache_key) ? args.fetch(:cache_key) : args + @logger.debug( + LogMessages::Util::ConcurrencyLimitedCacheKeyRetrieved.new( + cache_key + ) + ) + cache_key + end end end diff --git a/app/domain/util/rate_limited_cache.rb b/app/domain/util/rate_limited_cache.rb index 3678bdda89..4e43919278 100644 --- a/app/domain/util/rate_limited_cache.rb +++ b/app/domain/util/rate_limited_cache.rb @@ -43,17 +43,18 @@ def call(**args) args.delete(:refresh) @semaphore.synchronize do - first_calculation = !@cache.key?(args) - recalculate(args) if refresh_requested || first_calculation + cache_key = cached_key(args) + first_calculation = !@cache.key?(cache_key) + recalculate(args, cache_key) if refresh_requested || first_calculation - @cache[args] + @cache[cache_key] end end private - def recalculate(args) - if too_many_requests?(args) + def recalculate(args, cache_key) + if too_many_requests?(cache_key) @logger.debug( LogMessages::Util::RateLimitedCacheLimitReached.new( @refreshes_per_interval, @@ -62,9 +63,24 @@ def recalculate(args) ) return end - @cache[args] = @target.call(**args) + @cache[cache_key] = @target.call(**args) @logger.debug(LogMessages::Util::RateLimitedCacheUpdated.new) - @refresh_history[args].push(@time.now) + @refresh_history[cache_key].push(@time.now) + end + + def cached_key(args) + if args.key?(:cache_key) + cache_key = args.fetch(:cache_key) + args.delete(:cache_key) + cache_key + end + cache_key = args + @logger.debug( + LogMessages::Util::RateLimitedCacheKeyRetrieved.new( + cache_key + ) + ) + cache_key end def too_many_requests?(args) diff --git a/cucumber/authenticators_jwt/features/authn_jwt.feature b/cucumber/authenticators_jwt/features/authn_jwt.feature index 425c7c2981..bfb6e89986 100644 --- a/cucumber/authenticators_jwt/features/authn_jwt.feature +++ b/cucumber/authenticators_jwt/features/authn_jwt.feature @@ -12,8 +12,6 @@ Feature: JWT Authenticator - JWKs Basic sanity id: conjur/authn-jwt/raw body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on raw JWKs. - !variable id: jwks-uri @@ -38,13 +36,14 @@ Feature: JWT Authenticator - JWKs Basic sanity member: !host myapp """ And I am the super-user - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint + And I initialize remote JWKS endpoint with file "authn-jwt-general" and alg "RS256" + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-general/RS256" in service "raw" And I successfully set authn-jwt "token-app-property" variable to value "host" @sanity Scenario: ONYX-8598: Authenticator is not enabled Given I have a "variable" resource called "test-variable" - And I issue a JWT token: + And I am using file "authn-jwt-general" and alg "RS256" for remotely issue token: """ { "user":"myapp", @@ -68,7 +67,7 @@ Feature: JWT Authenticator - JWKs Basic sanity annotations: authn-jwt/raw/custom-claim: """ - And I issue a JWT token: + And I am using file "authn-jwt-general" and alg "RS256" for remotely issue token: """ { "host":"not_premmited", diff --git a/cucumber/authenticators_jwt/features/authn_jwt_check_standard_claims.feature b/cucumber/authenticators_jwt/features/authn_jwt_check_standard_claims.feature index c312633b46..799a948935 100644 --- a/cucumber/authenticators_jwt/features/authn_jwt_check_standard_claims.feature +++ b/cucumber/authenticators_jwt/features/authn_jwt_check_standard_claims.feature @@ -8,15 +8,13 @@ Feature: JWT Authenticator - Check registered claim - aud Background: - Given I initialize JWKS endpoint with file "myJWKs.json" + Given I initialize remote JWKS endpoint with file "authn-jwt-check-standard-claims" and alg "RS256" And I load a policy: """ - !policy id: conjur/authn-jwt/raw body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on raw JWKs. - !variable id: token-app-property @@ -88,9 +86,9 @@ Feature: JWT Authenticator - Check registered claim - !variable id: issuer """ - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-check-standard-claims/RS256" in service "raw" And I successfully set authn-jwt "issuer" variable to value "incorrect-value" - And I issue a JWT token: + And I am using file "authn-jwt-check-standard-claims" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -115,8 +113,8 @@ Feature: JWT Authenticator - Check registered claim - !variable id: jwks-uri """ - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint - And I issue a JWT token: + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-check-standard-claims/RS256" in service "raw" + And I am using file "authn-jwt-check-standard-claims" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -141,8 +139,8 @@ Feature: JWT Authenticator - Check registered claim - !variable id: jwks-uri """ - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint - And I issue a JWT token without exp: + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-check-standard-claims/RS256" in service "raw" + And I am using file "authn-jwt-check-standard-claims" and alg "RS256" for remotely issue non exp token: """ { "host":"myapp", @@ -166,8 +164,8 @@ Feature: JWT Authenticator - Check registered claim - !variable id: jwks-uri """ - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint - And I issue a JWT token: + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-check-standard-claims/RS256" in service "raw" + And I am using file "authn-jwt-check-standard-claims" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -192,8 +190,8 @@ Feature: JWT Authenticator - Check registered claim - !variable id: jwks-uri """ - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint - And I issue a JWT token: + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-check-standard-claims/RS256" in service "raw" + And I am using file "authn-jwt-check-standard-claims" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -221,8 +219,8 @@ Feature: JWT Authenticator - Check registered claim - !variable id: issuer """ - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint - And I issue a JWT token: + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-check-standard-claims/RS256" in service "raw" + And I am using file "authn-jwt-check-standard-claims" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -250,8 +248,8 @@ Feature: JWT Authenticator - Check registered claim - !variable id: issuer """ - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint - And I issue a JWT token: + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-check-standard-claims/RS256" in service "raw" + And I am using file "authn-jwt-check-standard-claims" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -279,9 +277,9 @@ Feature: JWT Authenticator - Check registered claim - !variable id: issuer """ - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-check-standard-claims/RS256" in service "raw" And I successfully set authn-jwt "issuer" variable to value "http://jwks" - And I issue a JWT token: + And I am using file "authn-jwt-check-standard-claims" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -310,9 +308,9 @@ Feature: JWT Authenticator - Check registered claim - !variable id: issuer """ - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint And I successfully set authn-jwt "issuer" variable to value "incorrect.com" - And I issue a JWT token: + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-check-standard-claims/RS256" in service "raw" + And I am using file "authn-jwt-check-standard-claims" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -342,12 +340,12 @@ Feature: JWT Authenticator - Check registered claim """ And I successfully set authn-jwt "jwks-uri" variable to value "incorrect.com" And I successfully set authn-jwt "issuer" variable to value "incorrect.com" - And I issue a JWT token: + And I am using file "authn-jwt-check-standard-claims" and alg "RS256" for remotely issue token: """ { "host":"myapp", "project-id": "myproject", - "iss": "http://jwks" + "iss": "http://jwks_py:8090/authn-jwt-check-standard-claims/RS256" } """ And I save my place in the audit log file @@ -387,9 +385,9 @@ Feature: JWT Authenticator - Check registered claim role: !group conjur/authn-jwt/raw/hosts member: !host aud-test-app """ - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-check-standard-claims/RS256" in service "raw" And I successfully set authn-jwt "audience" variable to value "" - And I issue a JWT token: + And I am using file "authn-jwt-check-standard-claims" and alg "RS256" for remotely issue token: """ { "project-id":"valid-project-id", diff --git a/cucumber/authenticators_jwt/features/authn_jwt_configuration.feature b/cucumber/authenticators_jwt/features/authn_jwt_configuration.feature index 8c422b140f..0b582b1eb1 100644 --- a/cucumber/authenticators_jwt/features/authn_jwt_configuration.feature +++ b/cucumber/authenticators_jwt/features/authn_jwt_configuration.feature @@ -3,7 +3,7 @@ Feature: JWT Authenticator - Configuration Check Tests to check failures because of misconfiguration of the JWT during runtime. Background: - Given I initialize JWKS endpoint with file "myJWKs.json" + Given I initialize remote JWKS endpoint with file "authn-jwt-configuration" and alg "RS256" And I have a "variable" resource called "test-variable" Scenario: ONYX-8600: Webservice is missing in Authenticator policy @@ -29,9 +29,9 @@ Feature: JWT Authenticator - Configuration Check member: !host myapp """ And I am the super-user - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-configuration/RS256" in service "raw" And I successfully set authn-jwt "token-app-property" variable to value "host" - And I issue a JWT token: + And I am using file "authn-jwt-configuration" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -53,8 +53,6 @@ Feature: JWT Authenticator - Configuration Check id: conjur/authn-jwt/raw body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on raw JWKs. - !variable id: jwks-uri @@ -73,9 +71,9 @@ Feature: JWT Authenticator - Configuration Check member: !host myapp """ And I am the super-user - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-configuration/RS256" in service "raw" And I successfully set authn-jwt "token-app-property" variable to value "host" - And I issue a JWT token: + And I am using file "authn-jwt-configuration" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -97,8 +95,6 @@ Feature: JWT Authenticator - Configuration Check id: conjur/authn-jwt/raw body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on raw JWKs. - !variable id: jwks-uri @@ -127,7 +123,7 @@ Feature: JWT Authenticator - Configuration Check And I am the super-user And I successfully set authn-jwt "jwks-uri" variable to value "jwks uri placehodlder" And I successfully set authn-jwt "provider-uri" variable to value "provider uri placeholder" - And I issue a JWT token: + And I am using file "authn-jwt-configuration" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -149,8 +145,6 @@ Feature: JWT Authenticator - Configuration Check id: conjur/authn-jwt/raw body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on raw JWKs. - !variable id: jwks-uri @@ -179,7 +173,7 @@ Feature: JWT Authenticator - Configuration Check And I am the super-user And I successfully set authn-jwt "jwks-uri" variable to value " " And I successfully set authn-jwt "provider-uri" variable to value "provider uri placeholder" - And I issue a JWT token: + And I am using file "authn-jwt-configuration" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -201,8 +195,6 @@ Feature: JWT Authenticator - Configuration Check id: conjur/authn-jwt/raw body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on raw JWKs. - !variable id: jwks-uri @@ -226,7 +218,7 @@ Feature: JWT Authenticator - Configuration Check member: !host myapp """ And I am the super-user - And I issue a JWT token: + And I am using file "authn-jwt-configuration" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -248,8 +240,6 @@ Feature: JWT Authenticator - Configuration Check id: conjur/authn-jwt/raw body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on raw JWKs. - !variable id: provider-uri @@ -273,7 +263,7 @@ Feature: JWT Authenticator - Configuration Check member: !host myapp """ And I am the super-user - And I issue a JWT token: + And I am using file "authn-jwt-configuration" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -295,8 +285,6 @@ Feature: JWT Authenticator - Configuration Check id: conjur/authn-jwt/raw body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on raw JWKs. - !variable id: token-app-property @@ -317,7 +305,7 @@ Feature: JWT Authenticator - Configuration Check member: !host myapp """ And I am the super-user - And I issue a JWT token: + And I am using file "authn-jwt-configuration" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -339,8 +327,6 @@ Feature: JWT Authenticator - Configuration Check id: conjur/authn-jwt/raw body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on raw JWKs. - !variable id: jwks-uri @@ -367,9 +353,9 @@ Feature: JWT Authenticator - Configuration Check member: !host myapp """ And I am the super-user - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-configuration/RS256" in service "raw" And I successfully set authn-jwt "provider-uri" variable to value " " - And I issue a JWT token: + And I am using file "authn-jwt-configuration" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -391,8 +377,6 @@ Feature: JWT Authenticator - Configuration Check id: conjur/authn-jwt/raw body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on raw JWKs. - !variable id: jwks-uri @@ -416,8 +400,8 @@ Feature: JWT Authenticator - Configuration Check member: !host myapp """ And I successfully set authn-jwt "token-app-property" variable to value "host" - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint - And I issue a JWT token: + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-configuration/RS256" in service "raw" + And I am using file "authn-jwt-configuration" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -439,8 +423,6 @@ Feature: JWT Authenticator - Configuration Check id: conjur/authn-jwt/raw body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on raw JWKs. - !variable id: jwks-uri @@ -460,8 +442,8 @@ Feature: JWT Authenticator - Configuration Check role: !group conjur/authn-jwt/raw/hosts member: !host myapp """ - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint - And I issue a JWT token: + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-configuration/RS256" in service "raw" + And I am using file "authn-jwt-configuration" and alg "RS256" for remotely issue token: """ { "host":"myapp", diff --git a/cucumber/authenticators_jwt/features/authn_jwt_fetch_identity_decoded_token.feature b/cucumber/authenticators_jwt/features/authn_jwt_fetch_identity_decoded_token.feature index 1a2b84da17..add6ec8a03 100644 --- a/cucumber/authenticators_jwt/features/authn_jwt_fetch_identity_decoded_token.feature +++ b/cucumber/authenticators_jwt/features/authn_jwt_fetch_identity_decoded_token.feature @@ -5,15 +5,12 @@ Feature: JWT Authenticator - Fetch identity from decoded token * 'identity-path' - prefix of the host connecting with JWT authenticator Background: - Given I initialize JWKS endpoint with file "myJWKs.json" - And I load a policy: + Given I load a policy: """ - !policy id: conjur/authn-jwt/raw body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on raw JWKs. - !variable id: jwks-uri @@ -56,15 +53,16 @@ Feature: JWT Authenticator - Fetch identity from decoded token member: !host some_policy/host_test_from_token """ And I am the super-user - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint + And I have a "variable" resource called "test-variable" + And I initialize remote JWKS endpoint with file "identity-from-decoded-token" and alg "RS256" + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/identity-from-decoded-token/RS256" in service "raw" @sanity Scenario: ONYX-8820: A valid JWT token with identity in the token - Given I have a "variable" resource called "test-variable" - And I successfully set authn-jwt "token-app-property" variable to value "host" + Given I successfully set authn-jwt "token-app-property" variable to value "host" And I permit host "myapp" to "execute" it And I add the secret value "test-secret" to the resource "cucumber:variable:test-variable" - And I issue a JWT token: + And I am using file "identity-from-decoded-token" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -94,7 +92,7 @@ Feature: JWT Authenticator - Fetch identity from decoded token role: !group conjur/authn-jwt/raw/hosts member: !user myuser """ - And I issue a JWT token: + And I am using file "identity-from-decoded-token" and alg "RS256" for remotely issue token: """ { "host":"myapp2", @@ -110,7 +108,7 @@ Feature: JWT Authenticator - Fetch identity from decoded token """ Scenario: ONYX-8825: Token identity configuration not matching any claim, error - Given I issue a JWT token: + Given I am using file "identity-from-decoded-token" and alg "RS256" for remotely issue token: """ { "project-id": "myproject" @@ -126,7 +124,7 @@ Feature: JWT Authenticator - Fetch identity from decoded token """ Scenario: ONYX-8824: Token identity configuration with empty secret, no identity in URL, error - Given I issue a JWT token: + Given I am using file "identity-from-decoded-token" and alg "RS256" for remotely issue token: """ { "project-id": "myproject" @@ -155,7 +153,7 @@ Feature: JWT Authenticator - Fetch identity from decoded token And I successfully set authn-jwt "identity-path" variable to value "some_policy/" And I permit host "some_policy/sub_policy/host_test_from_token" to "execute" it And I add the secret value "test-secret" to the resource "cucumber:variable:test-variable" - And I issue a JWT token: + And I am using file "identity-from-decoded-token" and alg "RS256" for remotely issue token: """ { "host_claim":"sub_policy/host_test_from_token", @@ -186,7 +184,7 @@ Feature: JWT Authenticator - Fetch identity from decoded token And I successfully set authn-jwt "identity-path" variable to value "some_policy/" And I permit host "some_policy/host_test_from_token" to "execute" it And I add the secret value "test-secret" to the resource "cucumber:variable:test-variable" - And I issue a JWT token: + And I am using file "identity-from-decoded-token" and alg "RS256" for remotely issue token: """ { "host_claim":"host_test_from_token", diff --git a/cucumber/authenticators_jwt/features/authn_jwt_fetch_identity_from_url.feature b/cucumber/authenticators_jwt/features/authn_jwt_fetch_identity_from_url.feature index 04f516292f..bacccb5d7a 100644 --- a/cucumber/authenticators_jwt/features/authn_jwt_fetch_identity_from_url.feature +++ b/cucumber/authenticators_jwt/features/authn_jwt_fetch_identity_from_url.feature @@ -3,15 +3,12 @@ Feature: JWT Authenticator - Fetch identity from URL Tests for fetching identity from URL of the JWT authentication request. Background: - Given I initialize JWKS endpoint with file "myJWKs.json" - And I load a policy: + Given I load a policy: """ - !policy id: conjur/authn-jwt/raw body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on raw JWKs. - !variable id: jwks-uri @@ -60,13 +57,14 @@ Feature: JWT Authenticator - Fetch identity from URL member: !user user_test_from_url """ And I am the super-user - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint + And I initialize remote JWKS endpoint with file "identity-from-url" and alg "RS256" + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/identity-from-url/RS256" in service "raw" Scenario: ONYX-9520: User send in URL, user not in root, 200 ok Given I have a "variable" resource called "test-variable" And I permit user "user_test_from_url@some_policy" to "execute" it And I add the secret value "test-secret" to the resource "cucumber:variable:test-variable" - And I issue a JWT token: + And I am using file "identity-from-url" and alg "RS256" for remotely issue token: """ { "project-id": "myproject" @@ -85,7 +83,7 @@ Feature: JWT Authenticator - Fetch identity from URL Given I have a "variable" resource called "test-variable" And I permit user "user_test_from_url" to "execute" it And I add the secret value "test-secret" to the resource "cucumber:variable:test-variable" - And I issue a JWT token: + And I am using file "identity-from-url" and alg "RS256" for remotely issue token: """ { "project-id": "myproject" @@ -104,7 +102,7 @@ Feature: JWT Authenticator - Fetch identity from URL Given I have a "variable" resource called "test-variable" And I permit host "some_policy/host_test_from_url" to "execute" it And I add the secret value "test-secret" to the resource "cucumber:variable:test-variable" - And I issue a JWT token: + And I am using file "identity-from-url" and alg "RS256" for remotely issue token: """ { "project-id": "myproject" @@ -123,7 +121,7 @@ Feature: JWT Authenticator - Fetch identity from URL Given I have a "variable" resource called "test-variable" And I permit host "myapp" to "execute" it And I add the secret value "test-secret" to the resource "cucumber:variable:test-variable" - And I issue a JWT token: + And I am using file "identity-from-url" and alg "RS256" for remotely issue token: """ { "project-id": "myproject" @@ -139,7 +137,7 @@ Feature: JWT Authenticator - Fetch identity from URL """ Scenario: ONYX-8821: Host taken from URL but not defined in conjur, error - Given I issue a JWT token: + Given I am using file "identity-from-url" and alg "RS256" for remotely issue token: """ { "project-id": "myproject" @@ -165,7 +163,7 @@ Feature: JWT Authenticator - Fetch identity from URL - !variable id: identity-path """ - And I issue a JWT token: + And I am using file "identity-from-url" and alg "RS256" for remotely issue token: """ { "project-id": "myproject" diff --git a/cucumber/authenticators_jwt/features/authn_jwt_fetch_signing_key.feature b/cucumber/authenticators_jwt/features/authn_jwt_fetch_signing_key.feature index 2490f9606b..79a49b3b58 100644 --- a/cucumber/authenticators_jwt/features/authn_jwt_fetch_signing_key.feature +++ b/cucumber/authenticators_jwt/features/authn_jwt_fetch_signing_key.feature @@ -10,8 +10,6 @@ Feature: JWT Authenticator - Fetch signing key id: conjur/authn-jwt/keycloak body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on Keycloak as OIDC provider. - !variable id: provider-uri @@ -47,16 +45,14 @@ Feature: JWT Authenticator - Fetch signing key When I authenticate via authn-jwt with the ID token Then host "alice" has been authorized by Conjur + # BUG: ONYX-10132 , expected error code should be 401 Scenario: ONYX-8704: provider uri configured with bad value - Given I initialize JWKS endpoint with file "myJWKs.json" - And I load a policy: + Given I load a policy: """ - !policy - id: conjur/authn-jwt/raw + id: conjur/authn-jwt/keycloak body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on raw JWKs. - !variable id: provider-uri @@ -72,63 +68,33 @@ Feature: JWT Authenticator - Fetch signing key resource: !webservice - !host - id: myapp - annotations: - authn-jwt/raw/project-id: myproject - - - !grant - role: !group conjur/authn-jwt/raw/hosts - member: !host myapp - - - !host - id: some_policy/sub_policy/host_test_from_token - annotations: - authn-jwt/raw/project-id: myproject - - - !grant - role: !group conjur/authn-jwt/raw/hosts - member: !host some_policy/sub_policy/host_test_from_token - - - !host - id: some_policy/host_test_from_token + id: alice annotations: - authn-jwt/raw/project-id: myproject + authn-jwt/keycloak/email: alice@conjur.net - !grant - role: !group conjur/authn-jwt/raw/hosts - member: !host some_policy/host_test_from_token + role: !group conjur/authn-jwt/keycloak/hosts + member: !host alice """ And I am the super-user - And I have a "variable" resource called "test-variable" - And I successfully set authn-jwt "provider-uri" variable to value "unknown-host.com" - And I successfully set authn-jwt "token-app-property" variable to value "host" - And I permit host "myapp" to "execute" it - And I add the secret value "test-secret" to the resource "cucumber:variable:test-variable" - And I issue a JWT token: - """ - { - "host":"myapp", - "project-id": "myproject" - } - """ + And I successfully set authn-jwt "provider-uri" variable value to "unknown-host.com" in service "keycloak" + And I successfully set authn-jwt "token-app-property" variable value to "host" in service "keycloak" And I save my place in the log file - When I authenticate via authn-jwt with the JWT token + And I fetch an ID Token for username "alice" and password "alice" + When I authenticate via authn-jwt with the ID token Then the HTTP response status code is 502 And The following appears in the log after my savepoint: """ - CONJ00011E Failed to discover Identity Provider + CONJ00011E Failed to discover Identity Provider (Provider URI: 'unknown-host.com') """ Scenario: ONYX-8703: jwks uri configured with correct value - Given I initialize JWKS endpoint with file "myJWKs.json" - And I load a policy: + Given I load a policy: """ - !policy id: conjur/authn-jwt/raw body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on raw JWKs. - !variable id: jwks-uri @@ -151,32 +117,15 @@ Feature: JWT Authenticator - Fetch signing key - !grant role: !group conjur/authn-jwt/raw/hosts member: !host myapp - - - !host - id: some_policy/sub_policy/host_test_from_token - annotations: - authn-jwt/raw/project-id: myproject - - - !grant - role: !group conjur/authn-jwt/raw/hosts - member: !host some_policy/sub_policy/host_test_from_token - - - !host - id: some_policy/host_test_from_token - annotations: - authn-jwt/raw/project-id: myproject - - - !grant - role: !group conjur/authn-jwt/raw/hosts - member: !host some_policy/host_test_from_token """ And I am the super-user - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint + And I initialize remote JWKS endpoint with file "authn-jwt-fetch-signing-key" and alg "RS256" + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-fetch-signing-key/RS256" in service "raw" And I have a "variable" resource called "test-variable" And I successfully set authn-jwt "token-app-property" variable to value "host" And I permit host "myapp" to "execute" it And I add the secret value "test-secret" to the resource "cucumber:variable:test-variable" - And I issue a JWT token: + And I am using file "authn-jwt-fetch-signing-key" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -193,15 +142,12 @@ Feature: JWT Authenticator - Fetch signing key """ Scenario: ONYX-8705: jwks uri configured with bad value - Given I initialize JWKS endpoint with file "myJWKs.json" - And I load a policy: + Given I load a policy: """ - !policy id: conjur/authn-jwt/raw body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on raw JWKs. - !variable id: jwks-uri @@ -224,32 +170,12 @@ Feature: JWT Authenticator - Fetch signing key - !grant role: !group conjur/authn-jwt/raw/hosts member: !host myapp - - - !host - id: some_policy/sub_policy/host_test_from_token - annotations: - authn-jwt/raw/project-id: myproject - - - !grant - role: !group conjur/authn-jwt/raw/hosts - member: !host some_policy/sub_policy/host_test_from_token - - - !host - id: some_policy/host_test_from_token - annotations: - authn-jwt/raw/project-id: myproject - - - !grant - role: !group conjur/authn-jwt/raw/hosts - member: !host some_policy/host_test_from_token """ And I am the super-user - And I have a "variable" resource called "test-variable" + And I initialize remote JWKS endpoint with file "authn-jwt-fetch-signing-key" and alg "RS256" And I successfully set authn-jwt "jwks-uri" variable to value "unknown-host.com" And I successfully set authn-jwt "token-app-property" variable to value "host" - And I permit host "myapp" to "execute" it - And I add the secret value "test-secret" to the resource "cucumber:variable:test-variable" - And I issue a JWT token: + And I am using file "authn-jwt-fetch-signing-key" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -265,15 +191,12 @@ Feature: JWT Authenticator - Fetch signing key """ Scenario: ONYX-8708: provider uri configured dynamically changed to jwks uri - Given I initialize JWKS endpoint with file "myJWKs.json" - And I load a policy: + Given I load a policy: """ - !policy id: conjur/authn-jwt/keycloak body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on keycloak JWKs. - !variable id: provider-uri @@ -291,15 +214,6 @@ Feature: JWT Authenticator - Fetch signing key privilege: [ read, authenticate ] resource: !webservice - - !host - id: myapp - annotations: - authn-jwt/keycloak/project-id: myproject - - - !grant - role: !group conjur/authn-jwt/keycloak/hosts - member: !host myapp - - !host id: alice annotations: @@ -317,54 +231,66 @@ Feature: JWT Authenticator - Fetch signing key And I save my place in the log file And I authenticate via authn-jwt with the ID token And host "alice" has been authorized by Conjur - When I update the policy with: - """ - - !policy - id: conjur/authn-jwt/keycloak - body: - - !delete - record: !variable provider-uri - """ - And I extend the policy with: + When I replace the "root" policy with: """ - !policy id: conjur/authn-jwt/keycloak body: + - !webservice + - !variable id: jwks-uri + + - !variable + id: token-app-property + + - !group hosts + + - !permit + role: !group hosts + privilege: [ read, authenticate ] + resource: !webservice + + - !host + id: alice + annotations: + authn-jwt/keycloak/email: alice@conjur.net + + - !grant + role: !group conjur/authn-jwt/keycloak/hosts + member: !host alice """ And I am the super-user - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" in service "keycloak" + And I initialize remote JWKS endpoint with file "authn-jwt-fetch-signing-key" and alg "RS256" + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-fetch-signing-key/RS256" in service "keycloak" And I have a "variable" resource called "test-variable" And I successfully set authn-jwt "token-app-property" variable value to "host" in service "keycloak" - And I permit host "myapp" to "execute" it + And I permit host "alice" to "execute" it And I add the secret value "test-secret" to the resource "cucumber:variable:test-variable" - And I issue a JWT token: + And I am using file "authn-jwt-fetch-signing-key" and alg "RS256" for remotely issue token: """ { - "host":"myapp", - "project-id": "myproject" + "host":"alice", + "project-id": "myproject", + "email": "alice@conjur.net" } """ And I save my place in the log file And I authenticate via authn-jwt using given keycloak service ID and without account in url - Then host "myapp" has been authorized by Conjur + Then host "alice" has been authorized by Conjur And I successfully GET "/secrets/cucumber/variable/test-variable" with authorized user And The following appears in the log after my savepoint: """ - cucumber:host:myapp successfully authenticated with authenticator authn-jwt service cucumber:webservice:conjur/authn-jwt/keycloak + cucumber:host:alice successfully authenticated with authenticator authn-jwt service cucumber:webservice:conjur/authn-jwt/keycloak """ Scenario: jwks uri configured dynamically changed to provider uri - Given I initialize JWKS endpoint with file "myJWKs.json" - And I load a policy: + Given I load a policy: """ - !policy id: conjur/authn-jwt/keycloak body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on keycloak JWKs. - !variable id: jwks-uri @@ -372,9 +298,6 @@ Feature: JWT Authenticator - Fetch signing key - !variable id: token-app-property - - !variable - id: issuer - - !group hosts - !permit @@ -382,15 +305,6 @@ Feature: JWT Authenticator - Fetch signing key privilege: [ read, authenticate ] resource: !webservice - - !host - id: myapp - annotations: - authn-jwt/keycloak/project-id: myproject - - - !grant - role: !group conjur/authn-jwt/keycloak/hosts - member: !host myapp - - !host id: alice annotations: @@ -401,41 +315,59 @@ Feature: JWT Authenticator - Fetch signing key member: !host alice """ And I am the super-user - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" in service "keycloak" + And I initialize remote JWKS endpoint with file "authn-jwt-fetch-signing-key" and alg "RS256" + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-fetch-signing-key/RS256" in service "keycloak" And I have a "variable" resource called "test-variable" And I successfully set authn-jwt "token-app-property" variable value to "host" in service "keycloak" - And I permit host "myapp" to "execute" it + And I permit host "alice" to "execute" it And I add the secret value "test-secret" to the resource "cucumber:variable:test-variable" - And I issue a JWT token: + And I am using file "authn-jwt-fetch-signing-key" and alg "RS256" for remotely issue token: """ { - "host":"myapp", - "project-id": "myproject" + "host":"alice", + "project-id": "myproject", + "email": "alice@conjur.net" } """ And I save my place in the log file And I authenticate via authn-jwt using given keycloak service ID and without account in url - And host "myapp" has been authorized by Conjur + And host "alice" has been authorized by Conjur And I successfully GET "/secrets/cucumber/variable/test-variable" with authorized user And The following appears in the log after my savepoint: """ - cucumber:host:myapp successfully authenticated with authenticator authn-jwt service cucumber:webservice:conjur/authn-jwt/keycloak + cucumber:host:alice successfully authenticated with authenticator authn-jwt service cucumber:webservice:conjur/authn-jwt/keycloak """ - When I update the policy with: - """ - - !policy - id: conjur/authn-jwt/keycloak - body: - - !delete - record: !variable jwks-uri - """ - And I extend the policy with: + When I replace the "root" policy with: """ - !policy id: conjur/authn-jwt/keycloak body: + - !webservice + - !variable id: provider-uri + + - !variable + id: token-app-property + + - !variable + id: issuer + + - !group hosts + + - !permit + role: !group hosts + privilege: [ read, authenticate ] + resource: !webservice + + - !host + id: alice + annotations: + authn-jwt/keycloak/email: alice@conjur.net + + - !grant + role: !group conjur/authn-jwt/keycloak/hosts + member: !host alice """ And I am the super-user And I successfully set authn-jwt "provider-uri" variable with OIDC value from env var "PROVIDER_URI" @@ -448,15 +380,12 @@ Feature: JWT Authenticator - Fetch signing key @sanity Scenario: ONYX-8709: provider-uri dynamically changed, 502 ERROR resolves to 200 OK - Given I initialize JWKS endpoint with file "myJWKs.json" - And I load a policy: + Given I load a policy: """ - !policy id: conjur/authn-jwt/keycloak body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on keycloak JWKs. - !variable id: provider-uri @@ -512,15 +441,13 @@ Feature: JWT Authenticator - Fetch signing key @sanity Scenario: ONYX-8710: jwks-uri dynamically changed, 401 ERROR resolves 200 OK - Given I initialize JWKS endpoint with file "myJWKs.json" + Given I initialize remote JWKS endpoint with file "authn-jwt-fetch-signing-key" and alg "RS256" And I load a policy: """ - !policy id: conjur/authn-jwt/raw body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on raw JWKs. - !variable id: jwks-uri @@ -545,13 +472,12 @@ Feature: JWT Authenticator - Fetch signing key member: !host myapp """ And I am the super-user - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint And I successfully set authn-jwt "token-app-property" variable to value "host" And I have a "variable" resource called "test-variable" And I add the secret value "test-secret" to the resource "cucumber:variable:test-variable" And I permit host "myapp" to "execute" it And I successfully set authn-jwt "jwks-uri" variable to value "incorrect.com" - And I issue a JWT token: + And I am using file "authn-jwt-fetch-signing-key" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -565,7 +491,7 @@ Feature: JWT Authenticator - Fetch signing key """ CONJ00087E Failed to fetch JWKS from 'incorrect.com' """ - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-fetch-signing-key/RS256" in service "raw" And I save my place in the audit log file When I authenticate via authn-jwt with raw service ID Then host "myapp" has been authorized by Conjur @@ -584,8 +510,6 @@ Feature: JWT Authenticator - Fetch signing key id: conjur/authn-jwt/raw body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on raw JWKs. - !variable id: jwks-uri diff --git a/cucumber/authenticators_jwt/features/authn_jwt_input_validation.feature b/cucumber/authenticators_jwt/features/authn_jwt_input_validation.feature index 55e6b0f19c..3254e438f9 100644 --- a/cucumber/authenticators_jwt/features/authn_jwt_input_validation.feature +++ b/cucumber/authenticators_jwt/features/authn_jwt_input_validation.feature @@ -3,15 +3,12 @@ Feature: JWT Authenticator - Input Validation Check scenarios with authentication request Background: - Given I initialize JWKS endpoint with file "myJWKs.json" - And I load a policy: + Given I load a policy: """ - !policy id: conjur/authn-jwt/raw body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on raw JWKs. - !variable id: jwks-uri @@ -33,12 +30,16 @@ Feature: JWT Authenticator - Input Validation member: !user myuser """ And I am the super-user - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint + And I initialize remote JWKS endpoint with file "authn-jwt-input-validation" and alg "RS256" + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-input-validation/RS256" in service "raw" @sanity Scenario: ONYX-8594: Empty Token Given, 401 Error Given I save my place in the log file - And I issue empty JWT token + And I am using file "authn-jwt-input-validation" and alg "RS256" for remotely issue non exp token: + """ + {} + """ When I authenticate via authn-jwt with the JWT token Then the HTTP response status code is 401 And The following appears in the log after my savepoint: @@ -68,7 +69,7 @@ Feature: JWT Authenticator - Input Validation Scenario: ONYX-8579: URL not includes service-id, includes correct account Given I save my place in the log file - And I issue a JWT token: + And I am using file "authn-jwt-input-validation" and alg "RS256" for remotely issue non exp token: """ { "project-id": "myproject" @@ -83,7 +84,7 @@ Feature: JWT Authenticator - Input Validation Scenario: ONYX-8579: URL includes valid service id, wrong account name Given I save my place in the log file - And I issue a JWT token: + And I am using file "authn-jwt-input-validation" and alg "RS256" for remotely issue token: """ { "project-id": "myproject" @@ -98,7 +99,7 @@ Feature: JWT Authenticator - Input Validation Scenario: ONYX-8579: URL includes wrong service id, correct account name Given I save my place in the log file - And I issue a JWT token: + And I am using file "authn-jwt-input-validation" and alg "RS256" for remotely issue non exp token: """ { "project-id": "myproject" @@ -110,4 +111,3 @@ Feature: JWT Authenticator - Input Validation """ CONJ00004E 'authn-jwt/wrong-id' is not enabled> """ - diff --git a/cucumber/authenticators_jwt/features/authn_jwt_security.feature b/cucumber/authenticators_jwt/features/authn_jwt_security.feature index 91b50132d2..b29b67c8d2 100644 --- a/cucumber/authenticators_jwt/features/authn_jwt_security.feature +++ b/cucumber/authenticators_jwt/features/authn_jwt_security.feature @@ -10,8 +10,6 @@ Feature: JWT Authenticator - Security id: conjur/authn-jwt/raw body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on raw JWKs. - !variable id: jwks-uri diff --git a/cucumber/authenticators_jwt/features/authn_jwt_token_schema.feature b/cucumber/authenticators_jwt/features/authn_jwt_token_schema.feature index af5183a638..aaac37ef47 100644 --- a/cucumber/authenticators_jwt/features/authn_jwt_token_schema.feature +++ b/cucumber/authenticators_jwt/features/authn_jwt_token_schema.feature @@ -3,15 +3,12 @@ Feature: JWT Authenticator - Token Schema Tests checking enforced claims and claims mapping Background: - Given I initialize JWKS endpoint with file "myJWKs.json" - And I load a policy: + Given I load a policy: """ - !policy id: conjur/authn-jwt/raw body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on raw JWKs. - !variable id: jwks-uri @@ -27,7 +24,8 @@ Feature: JWT Authenticator - Token Schema resource: !webservice """ And I am the super-user - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint + And I initialize remote JWKS endpoint with file "authn-jwt-token-schema" and alg "RS256" + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-token-schema/RS256" in service "raw" And I have a "variable" resource called "test-variable" And I successfully set authn-jwt "token-app-property" variable to value "host" @@ -49,7 +47,7 @@ Feature: JWT Authenticator - Token Schema And I successfully set authn-jwt "enforced-claims" variable to value "ref" And I add the secret value "test-secret" to the resource "cucumber:variable:test-variable" And I permit host "myapp" to "execute" it - And I issue a JWT token: + And I am using file "authn-jwt-token-schema" and alg "RS256" for remotely issue token: """ { "ref":"valid", @@ -83,7 +81,7 @@ Feature: JWT Authenticator - Token Schema And I successfully set authn-jwt "enforced-claims" variable to value "ref,sub" And I add the secret value "test-secret" to the resource "cucumber:variable:test-variable" And I permit host "myapp" to "execute" it - And I issue a JWT token: + And I am using file "authn-jwt-token-schema" and alg "RS256" for remotely issue token: """ { "ref":"valid-ref", @@ -115,7 +113,7 @@ Feature: JWT Authenticator - Token Schema member: !host myapp """ And I successfully set authn-jwt "enforced-claims" variable to value "ref" - And I issue a JWT token: + And I am using file "authn-jwt-token-schema" and alg "RS256" for remotely issue token: """ { "ref":"valid", @@ -145,7 +143,7 @@ Feature: JWT Authenticator - Token Schema member: !host myapp """ And I successfully set authn-jwt "enforced-claims" variable to value "ref" - And I issue a JWT token: + And I am using file "authn-jwt-token-schema" and alg "RS256" for remotely issue token: """ { "host":"myapp" @@ -174,7 +172,7 @@ Feature: JWT Authenticator - Token Schema member: !host myapp """ And I successfully set authn-jwt "enforced-claims" variable to value "" - And I issue a JWT token: + And I am using file "authn-jwt-token-schema" and alg "RS256" for remotely issue token: """ { "host":"myapp" @@ -205,7 +203,7 @@ Feature: JWT Authenticator - Token Schema role: !group conjur/authn-jwt/raw/hosts member: !host myapp """ - And I issue a JWT token: + And I am using file "authn-jwt-token-schema" and alg "RS256" for remotely issue token: """ { "host":"myapp" @@ -238,7 +236,7 @@ Feature: JWT Authenticator - Token Schema member: !host myapp """ And I successfully set authn-jwt "mapping-claims" variable to value "branch:ref" - And I issue a JWT token: + And I am using file "authn-jwt-token-schema" and alg "RS256" for remotely issue token: """ { "ref":"valid", @@ -268,7 +266,7 @@ Feature: JWT Authenticator - Token Schema """ And I add the secret value "test-secret" to the resource "cucumber:variable:test-variable" And I permit host "myapp" to "execute" it - And I issue a JWT token: + And I am using file "authn-jwt-token-schema" and alg "RS256" for remotely issue token: """ { "sub":"valid-sub", @@ -330,7 +328,7 @@ Feature: JWT Authenticator - Token Schema member: !host myapp """ And I successfully set authn-jwt "mapping-claims" variable to value "branch:ref" - And I issue a JWT token: + And I am using file "authn-jwt-token-schema" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -363,7 +361,7 @@ Feature: JWT Authenticator - Token Schema member: !host myapp """ And I successfully set authn-jwt "mapping-claims" variable to value "branch:ref" - And I issue a JWT token: + And I am using file "authn-jwt-token-schema" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -391,7 +389,7 @@ Feature: JWT Authenticator - Token Schema role: !group conjur/authn-jwt/raw/hosts member: !host myapp """ - And I issue a JWT token: + And I am using file "authn-jwt-token-schema" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -435,7 +433,7 @@ Feature: JWT Authenticator - Token Schema """ And I successfully set authn-jwt "mapping-claims" variable to value "branch:ref" And I successfully set authn-jwt "enforced-claims" variable to value "ref" - And I issue a JWT token: + And I am using file "authn-jwt-token-schema" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -467,7 +465,7 @@ Feature: JWT Authenticator - Token Schema """ And I successfully set authn-jwt "enforced-claims" variable to value "ref" And I successfully set authn-jwt "mapping-claims" variable to value "branch:ref" - And I issue a JWT token: + And I am using file "authn-jwt-token-schema" and alg "RS256" for remotely issue token: """ { "host":"myapp" @@ -496,7 +494,7 @@ Feature: JWT Authenticator - Token Schema member: !host myapp """ And I successfully set authn-jwt "mapping-claims" variable to value "sub:ref" - And I issue a JWT token: + And I am using file "authn-jwt-token-schema" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -512,7 +510,7 @@ Feature: JWT Authenticator - Token Schema CONJ00049E Resource restriction 'sub' does not match with the corresponding value in the request """ - Scenario: ONYX-10860 - Mapping claims configured but not populated - 401 Error + Scenario: ONYX-10861 - Mapping claims configured but not populated - 401 Error Given I extend the policy with: """ - !variable conjur/authn-jwt/raw/mapping-claims @@ -527,7 +525,7 @@ Feature: JWT Authenticator - Token Schema role: !group conjur/authn-jwt/raw/hosts member: !host myapp """ - And I issue a JWT token: + And I am using file "authn-jwt-token-schema" and alg "RS256" for remotely issue token: """ { "ref":"valid", @@ -563,7 +561,7 @@ Feature: JWT Authenticator - Token Schema """ And I successfully set authn-jwt "mapping-claims" variable to value "claim_ant:claim.ant..., _:claim_name" And I successfully set authn-jwt "enforced-claims" variable to value "claim.name, claim.ant..." - And I issue a JWT token: + And I am using file "authn-jwt-token-schema" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -596,7 +594,7 @@ Feature: JWT Authenticator - Token Schema member: !host myapp """ And I successfully set authn-jwt "mapping-claims" variable to value "" - And I issue a JWT token: + And I am using file "authn-jwt-token-schema" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -632,7 +630,7 @@ Feature: JWT Authenticator - Token Schema member: !host myapp """ And I successfully set authn-jwt "mapping-claims" variable to value "" - And I issue a JWT token: + And I am using file "authn-jwt-token-schema" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -668,7 +666,7 @@ Feature: JWT Authenticator - Token Schema """ And I successfully set authn-jwt "enforced-claims" variable to value "%@^#[{]}$~=-+_?.><&^@*@#*sdhj812ehd" And I permit host "myapp" to "execute" it - And I issue a JWT token: + And I am using file "authn-jwt-token-schema" and alg "RS256" for remotely issue token: """ { "ref":"valid", @@ -699,7 +697,7 @@ Feature: JWT Authenticator - Token Schema """ And I successfully set authn-jwt "mapping-claims" variable to value "aaa: %@^#&^[{]}$~=-+_?.><812ehd" And I permit host "myapp" to "execute" it - And I issue a JWT token: + And I am using file "authn-jwt-token-schema" and alg "RS256" for remotely issue token: """ { "ref":"valid", @@ -729,7 +727,7 @@ Feature: JWT Authenticator - Token Schema member: !host myapp """ And I successfully set authn-jwt "enforced-claims" variable to value "ref" - And I issue a JWT token: + And I am using file "authn-jwt-token-schema" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -803,7 +801,7 @@ Feature: JWT Authenticator - Token Schema member: !host myapp """ And I successfully set authn-jwt "mapping-claims" variable to value "branch:ref" - And I issue a JWT token: + And I am using file "authn-jwt-token-schema" and alg "RS256" for remotely issue token: """ { "host":"myapp", diff --git a/cucumber/authenticators_jwt/features/authn_jwt_validate_and_decode.feature b/cucumber/authenticators_jwt/features/authn_jwt_validate_and_decode.feature index 4e0a8c7ba9..4c3b198afc 100644 --- a/cucumber/authenticators_jwt/features/authn_jwt_validate_and_decode.feature +++ b/cucumber/authenticators_jwt/features/authn_jwt_validate_and_decode.feature @@ -9,8 +9,6 @@ Feature: JWT Authenticator - Validate And Decode id: conjur/authn-jwt/raw body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on raw JWKs. - !variable id: jwks-uri diff --git a/cucumber/authenticators_jwt/features/authn_jwt_validate_restrictions.feature b/cucumber/authenticators_jwt/features/authn_jwt_validate_restrictions.feature index 3b6b0445c7..e5d5e459ef 100644 --- a/cucumber/authenticators_jwt/features/authn_jwt_validate_restrictions.feature +++ b/cucumber/authenticators_jwt/features/authn_jwt_validate_restrictions.feature @@ -3,15 +3,12 @@ Feature: JWT Authenticator - Validate restrictions Tests to check that host annotations are validated correctly in jwt authenticator. Focusing on checking that only the vendor related annotations are being checked. Background: - Given I initialize JWKS endpoint with file "myJWKs.json" - And I load a policy: + Given I load a policy: """ - !policy id: conjur/authn-jwt/raw body: - !webservice - annotations: - description: Authentication service for JWT tokens, based on raw JWKs. - !variable id: jwks-uri @@ -27,7 +24,8 @@ Feature: JWT Authenticator - Validate restrictions resource: !webservice """ And I am the super-user - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint + And I initialize remote JWKS endpoint with file "authn-jwt-validate-restrictions" and alg "RS256" + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-validate-restrictions/RS256" in service "raw" Scenario: ONYX-9069: Generals annotations with valid values, one annotation with valid service and valid value, one annotation with invalid service and valid value, 200 OK Given I have a "variable" resource called "test-variable" @@ -48,7 +46,7 @@ Feature: JWT Authenticator - Validate restrictions And I successfully set authn-jwt "token-app-property" variable to value "host" And I add the secret value "test-secret" to the resource "cucumber:variable:test-variable" And I permit host "myapp" to "execute" it - And I issue a JWT token: + And I am using file "authn-jwt-validate-restrictions" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -79,7 +77,7 @@ Feature: JWT Authenticator - Validate restrictions role: !group conjur/authn-jwt/raw/hosts member: !host myapp """ - And I issue a JWT token: + And I am using file "authn-jwt-validate-restrictions" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -111,7 +109,7 @@ Feature: JWT Authenticator - Validate restrictions role: !group conjur/authn-jwt/raw/hosts member: !host myapp """ - And I issue a JWT token: + And I am using file "authn-jwt-validate-restrictions" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -138,7 +136,7 @@ Feature: JWT Authenticator - Validate restrictions role: !group conjur/authn-jwt/raw/hosts member: !host myapp """ - And I issue a JWT token: + And I am using file "authn-jwt-validate-restrictions" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -170,7 +168,7 @@ Feature: JWT Authenticator - Validate restrictions role: !group conjur/authn-jwt/raw/hosts member: !host myapp """ - And I issue a JWT token: + And I am using file "authn-jwt-validate-restrictions" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -203,7 +201,7 @@ Feature: JWT Authenticator - Validate restrictions role: !group conjur/authn-jwt/raw/hosts member: !host myapp """ - And I issue a JWT token: + And I am using file "authn-jwt-validate-restrictions" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -233,7 +231,7 @@ Feature: JWT Authenticator - Validate restrictions role: !group conjur/authn-jwt/raw/hosts member: !host myapp """ - And I issue a JWT token: + And I am using file "authn-jwt-validate-restrictions" and alg "RS256" for remotely issue token: """ { "host":"myapp" @@ -261,7 +259,7 @@ Feature: JWT Authenticator - Validate restrictions member: !host myapp """ And I successfully set authn-jwt "token-app-property" variable to value "host" - And I issue a JWT token: + And I am using file "authn-jwt-validate-restrictions" and alg "RS256" for remotely issue token: """ { "host":"myapp", @@ -296,7 +294,7 @@ Feature: JWT Authenticator - Validate restrictions member: !host myapp """ And I successfully set authn-jwt "token-app-property" variable to value "host" - And I issue a JWT token: + And I am using file "authn-jwt-validate-restrictions" and alg "RS256" for remotely issue token: """ { "host":"myapp", diff --git a/cucumber/authenticators_jwt/features/step_definitions/jwt_jwks_steps.rb b/cucumber/authenticators_jwt/features/step_definitions/jwt_jwks_steps.rb index fcb6aa8f9b..3922ac2b8e 100644 --- a/cucumber/authenticators_jwt/features/step_definitions/jwt_jwks_steps.rb +++ b/cucumber/authenticators_jwt/features/step_definitions/jwt_jwks_steps.rb @@ -126,3 +126,12 @@ ) ) end + +Given(/^I am using file "([^"]*)" and alg "([^"]*)" for remotely issue non exp token:$/) do |file_name, alg, token_body_string| + # token body has to be an object (not a string) for correct token creation + issue_jwt_token_remotely( + file_name, + alg, + JSON.parse(token_body_string) + ) +end From c4eedc7b95ee1fb5bd5a9581300614f13bbe880c Mon Sep 17 00:00:00 2001 From: Sasha Chernomordik Date: Mon, 9 Aug 2021 11:33:25 +0300 Subject: [PATCH 2/5] Adjust ValidateAndDecodeToken UTs --- .../validate_and_decode_token_spec.rb | 196 +++++++++++++----- 1 file changed, 146 insertions(+), 50 deletions(-) diff --git a/spec/app/domain/authentication/authn-jwt/validate_and_decode/validate_and_decode_token_spec.rb b/spec/app/domain/authentication/authn-jwt/validate_and_decode/validate_and_decode_token_spec.rb index a4fccaebe9..9642918ed4 100644 --- a/spec/app/domain/authentication/authn-jwt/validate_and_decode/validate_and_decode_token_spec.rb +++ b/spec/app/domain/authentication/authn-jwt/validate_and_decode/validate_and_decode_token_spec.rb @@ -45,6 +45,17 @@ ) } + let(:mocked_signing_key_interface_factory_valid) { double("MockedSigningKeyInterfaceFactoryValid") } + let(:mocked_signing_key_interface_factory_invalid) { double("MockedSigningKeyInterfaceFactoryInvalid") } + let(:mocked_signing_key_interface_factory_failed) { double("MockedSigningKeyInterfaceFactoryFailed") } + + let(:signing_key_interface_factory_error) { "signing key interface factory error" } + + let(:mocked_fetch_signing_key_interface_valid) { double("MockedSigningKeyInterfaceValid") } + let(:mocked_fetch_signing_key_interface_failed) { double("MockedSigningKeyInterfaceFailed") } + + let(:fetch_signing_key_interface_error) { "fetch signing key interface error" } + let(:mocked_fetch_signing_key_failed_on_1st_time) { double("MockedFetchSigningKeyInvalid") } let(:mocked_fetch_signing_key_failed_on_2nd_time) { double("MockedFetchSigningKeyInvalid") } let(:mocked_fetch_signing_key_always_succeed) { double("MockedFetchSigningKey") } @@ -67,6 +78,8 @@ def valid_decoded_token(claims) token_dictionary end + let(:valid_signing_key_uri) { "http://valid_signing_key_uri" } + let(:jwks_from_1st_call) { " jwks from 1st call "} let(:jwks_from_2nd_call) { " jwks from 2nd call "} let(:verification_options_for_signature_only_1st_call) { @@ -123,16 +136,48 @@ def valid_decoded_token(claims) let(:mocked_verify_and_decode_token_succeed_to_validate_claims_when_keys_updated) { double("MockedVerifyAndDecodeTokenSucceedToValidateClaims") } before(:each) do + allow(mocked_fetch_signing_key_interface_valid).to( + receive(:signing_key_uri).and_return(valid_signing_key_uri) + ) + + allow(mocked_signing_key_interface_factory_valid).to( + receive(:call).and_return(mocked_fetch_signing_key_interface_valid) + ) + + allow(mocked_fetch_signing_key_interface_failed).to( + receive(:signing_key_uri).and_raise(fetch_signing_key_interface_error) + ) + + allow(mocked_signing_key_interface_factory_invalid).to( + receive(:call).and_return(mocked_fetch_signing_key_interface_failed) + ) + + allow(mocked_signing_key_interface_factory_failed).to( + receive(:call).and_raise(signing_key_interface_factory_error) + ) + allow(mocked_fetch_signing_key_failed_on_1st_time).to( - receive(:call).with(refresh: false).and_raise(fetch_signing_key_1st_time_error) + receive(:call).with( + refresh: false, + cache_key: anything(), + signing_key_interface: anything() + ).and_raise(fetch_signing_key_1st_time_error) ) allow(mocked_fetch_signing_key_failed_on_2nd_time).to( - receive(:call).with(refresh: false).and_return(jwks_from_2nd_call) + receive(:call).with( + refresh: false, + cache_key: anything(), + signing_key_interface: anything() + ).and_return(jwks_from_2nd_call) ) allow(mocked_fetch_signing_key_failed_on_2nd_time).to( - receive(:call).with(refresh: true).and_raise(fetch_signing_key_2nd_time_error) + receive(:call).with( + refresh: true, + cache_key: anything(), + signing_key_interface: anything() + ).and_raise(fetch_signing_key_2nd_time_error) ) allow(mocked_verify_and_decode_token_invalid).to( @@ -140,11 +185,19 @@ def valid_decoded_token(claims) ) allow(mocked_fetch_signing_key_always_succeed).to( - receive(:call).with(refresh: false).and_return(jwks_from_1st_call) + receive(:call).with( + refresh: false, + cache_key: anything(), + signing_key_interface: anything() + ).and_return(jwks_from_1st_call) ) allow(mocked_fetch_signing_key_always_succeed).to( - receive(:call).with(refresh: true).and_return(jwks_from_2nd_call) + receive(:call).with( + refresh: true, + cache_key: anything(), + signing_key_interface: anything() + ).and_return(jwks_from_2nd_call) ) allow(mocked_verify_and_decode_token_succeed_on_1st_time).to( @@ -266,8 +319,7 @@ def valid_decoded_token(claims) context "with nil value" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new().call( - authentication_parameters: authentication_parameters_with_nil_token, - fetch_signing_key: ::Authentication::AuthnJwt::SigningKey::FetchSigningKeyInterface + authentication_parameters: authentication_parameters_with_nil_token ) end @@ -279,8 +331,7 @@ def valid_decoded_token(claims) context "with empty value" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new().call( - authentication_parameters: authentication_parameters_with_empty_token, - fetch_signing_key: ::Authentication::AuthnJwt::SigningKey::FetchSigningKeyInterface + authentication_parameters: authentication_parameters_with_empty_token ) end @@ -291,15 +342,49 @@ def valid_decoded_token(claims) end context "Failed to fetch keys" do - subject do - ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new().call( - authentication_parameters: authentication_parameters_with_valid_token, - fetch_signing_key: mocked_fetch_signing_key_failed_on_1st_time - ) + context "When error is during signing key factory call" do + subject do + ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( + fetch_signing_key_from_cache: mocked_fetch_signing_key_failed_on_1st_time, + signing_key_interface_factory: mocked_signing_key_interface_factory_failed + ).call( + authentication_parameters: authentication_parameters_with_valid_token + ) + end + + it "raises an error" do + expect { subject }.to raise_error(signing_key_interface_factory_error) + end + end + + context "When error is during signing_key_uri call" do + subject do + ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( + fetch_signing_key_from_cache: mocked_fetch_signing_key_failed_on_1st_time, + signing_key_interface_factory: mocked_signing_key_interface_factory_invalid + ).call( + authentication_parameters: authentication_parameters_with_valid_token + ) + end + + it "raises an error" do + expect { subject }.to raise_error(fetch_signing_key_interface_error) + end end - it "raises an error" do - expect { subject }.to raise_error(fetch_signing_key_1st_time_error) + context "When error is during fetching from cache" do + subject do + ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( + fetch_signing_key_from_cache: mocked_fetch_signing_key_failed_on_1st_time, + signing_key_interface_factory: mocked_signing_key_interface_factory_valid + ).call( + authentication_parameters: authentication_parameters_with_valid_token + ) + end + + it "raises an error" do + expect { subject }.to raise_error(fetch_signing_key_1st_time_error) + end end end @@ -308,10 +393,11 @@ def valid_decoded_token(claims) context "and failed to fetch keys from provider" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( - verify_and_decode_token: mocked_verify_and_decode_token_invalid + fetch_signing_key_from_cache: mocked_fetch_signing_key_failed_on_2nd_time, + verify_and_decode_token: mocked_verify_and_decode_token_invalid, + signing_key_interface_factory: mocked_signing_key_interface_factory_valid ).call( - authentication_parameters: authentication_parameters_with_valid_token, - fetch_signing_key: mocked_fetch_signing_key_failed_on_2nd_time + authentication_parameters: authentication_parameters_with_valid_token ) end @@ -323,10 +409,11 @@ def valid_decoded_token(claims) context "and succeed to fetch keys from provider" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( - verify_and_decode_token: mocked_verify_and_decode_token_invalid + fetch_signing_key_from_cache: mocked_fetch_signing_key_always_succeed, + verify_and_decode_token: mocked_verify_and_decode_token_invalid, + signing_key_interface_factory: mocked_signing_key_interface_factory_valid ).call( - authentication_parameters: authentication_parameters_with_valid_token, - fetch_signing_key: mocked_fetch_signing_key_always_succeed + authentication_parameters: authentication_parameters_with_valid_token ) end @@ -340,12 +427,13 @@ def valid_decoded_token(claims) context "and keys are not updated" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( + fetch_signing_key_from_cache: mocked_fetch_signing_key_always_succeed, verify_and_decode_token: mocked_verify_and_decode_token_succeed_on_2nd_time, fetch_jwt_claims_to_validate: mocked_fetch_jwt_claims_to_validate_valid, get_verification_option_by_jwt_claim: mocked_get_verification_option_by_jwt_claim_valid, + signing_key_interface_factory: mocked_signing_key_interface_factory_valid ).call( - authentication_parameters: authentication_parameters_with_valid_token, - fetch_signing_key: mocked_fetch_signing_key_always_succeed + authentication_parameters: authentication_parameters_with_valid_token ) end @@ -357,12 +445,13 @@ def valid_decoded_token(claims) context "and keys are updated" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( + fetch_signing_key_from_cache: mocked_fetch_signing_key_always_succeed, verify_and_decode_token: mocked_verify_and_decode_token_succeed_on_1st_time, fetch_jwt_claims_to_validate: mocked_fetch_jwt_claims_to_validate_valid, - get_verification_option_by_jwt_claim: mocked_get_verification_option_by_jwt_claim_valid - ).call( - authentication_parameters: authentication_parameters_with_valid_token, - fetch_signing_key: mocked_fetch_signing_key_always_succeed + get_verification_option_by_jwt_claim: mocked_get_verification_option_by_jwt_claim_valid, + signing_key_interface_factory: mocked_signing_key_interface_factory_valid + ).call( + authentication_parameters: authentication_parameters_with_valid_token ) end @@ -378,11 +467,12 @@ def valid_decoded_token(claims) context "and failed to fetch enforced claims" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( + fetch_signing_key_from_cache: mocked_fetch_signing_key_always_succeed, verify_and_decode_token: mocked_verify_and_decode_token_succeed_on_1st_time, - fetch_jwt_claims_to_validate: mocked_fetch_jwt_claims_to_validate_invalid - ).call( - authentication_parameters: authentication_parameters_with_valid_token, - fetch_signing_key: mocked_fetch_signing_key_always_succeed + fetch_jwt_claims_to_validate: mocked_fetch_jwt_claims_to_validate_invalid, + signing_key_interface_factory: mocked_signing_key_interface_factory_valid + ).call( + authentication_parameters: authentication_parameters_with_valid_token ) end @@ -395,11 +485,12 @@ def valid_decoded_token(claims) context "with empty claims list to validate" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( + fetch_signing_key_from_cache: mocked_fetch_signing_key_always_succeed, verify_and_decode_token: mocked_verify_and_decode_token_succeed_on_1st_time, - fetch_jwt_claims_to_validate: mocked_fetch_jwt_claims_to_validate_with_empty_claims + fetch_jwt_claims_to_validate: mocked_fetch_jwt_claims_to_validate_with_empty_claims, + signing_key_interface_factory: mocked_signing_key_interface_factory_valid ).call( - authentication_parameters: authentication_parameters_with_valid_token, - fetch_signing_key: mocked_fetch_signing_key_always_succeed, + authentication_parameters: authentication_parameters_with_valid_token ) end @@ -411,11 +502,12 @@ def valid_decoded_token(claims) context "with mandatory claims which do not exist in token" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( + fetch_signing_key_from_cache: mocked_fetch_signing_key_always_succeed, verify_and_decode_token: mocked_verify_and_decode_token_succeed_on_1st_time, - fetch_jwt_claims_to_validate: mocked_fetch_jwt_claims_to_validate_with_not_exist_claims_in_token + fetch_jwt_claims_to_validate: mocked_fetch_jwt_claims_to_validate_with_not_exist_claims_in_token, + signing_key_interface_factory: mocked_signing_key_interface_factory_valid ).call( - authentication_parameters: authentication_parameters_with_valid_token, - fetch_signing_key: mocked_fetch_signing_key_always_succeed + authentication_parameters: authentication_parameters_with_valid_token ) end @@ -427,12 +519,13 @@ def valid_decoded_token(claims) context "and failed to get verification options" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( + fetch_signing_key_from_cache: mocked_fetch_signing_key_always_succeed, verify_and_decode_token: mocked_verify_and_decode_token_succeed_on_1st_time, fetch_jwt_claims_to_validate: mocked_fetch_jwt_claims_to_validate_valid, - get_verification_option_by_jwt_claim: mocked_get_verification_option_by_jwt_claim_invalid + get_verification_option_by_jwt_claim: mocked_get_verification_option_by_jwt_claim_invalid, + signing_key_interface_factory: mocked_signing_key_interface_factory_valid ).call( - authentication_parameters: authentication_parameters_with_valid_token, - fetch_signing_key: mocked_fetch_signing_key_always_succeed + authentication_parameters: authentication_parameters_with_valid_token ) end @@ -451,12 +544,13 @@ def valid_decoded_token(claims) context "and failed to validate claims" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( + fetch_signing_key_from_cache: mocked_fetch_signing_key_always_succeed, verify_and_decode_token: mocked_verify_and_decode_token_failed_to_validate_claims, fetch_jwt_claims_to_validate: mocked_fetch_jwt_claims_to_validate_valid, - get_verification_option_by_jwt_claim: mocked_get_verification_option_by_jwt_claim_valid + get_verification_option_by_jwt_claim: mocked_get_verification_option_by_jwt_claim_valid, + signing_key_interface_factory: mocked_signing_key_interface_factory_valid ).call( - authentication_parameters: authentication_parameters_with_valid_token, - fetch_signing_key: mocked_fetch_signing_key_always_succeed + authentication_parameters: authentication_parameters_with_valid_token ) end @@ -469,12 +563,13 @@ def valid_decoded_token(claims) context "and keys are not updated" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( + fetch_signing_key_from_cache: mocked_fetch_signing_key_always_succeed, verify_and_decode_token: mocked_verify_and_decode_token_succeed_to_validate_claims_when_keys_not_updated, fetch_jwt_claims_to_validate: mocked_fetch_jwt_claims_to_validate_valid, - get_verification_option_by_jwt_claim: mocked_get_verification_option_by_jwt_claim_valid + get_verification_option_by_jwt_claim: mocked_get_verification_option_by_jwt_claim_valid, + signing_key_interface_factory: mocked_signing_key_interface_factory_valid ).call( - authentication_parameters: authentication_parameters_with_valid_token, - fetch_signing_key: mocked_fetch_signing_key_always_succeed + authentication_parameters: authentication_parameters_with_valid_token ) end @@ -486,12 +581,13 @@ def valid_decoded_token(claims) context "and keys are updated" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( + fetch_signing_key_from_cache: mocked_fetch_signing_key_always_succeed, verify_and_decode_token: mocked_verify_and_decode_token_succeed_to_validate_claims_when_keys_updated, fetch_jwt_claims_to_validate: mocked_fetch_jwt_claims_to_validate_valid, - get_verification_option_by_jwt_claim: mocked_get_verification_option_by_jwt_claim_valid + get_verification_option_by_jwt_claim: mocked_get_verification_option_by_jwt_claim_valid, + signing_key_interface_factory: mocked_signing_key_interface_factory_valid ).call( - authentication_parameters: authentication_parameters_with_valid_token, - fetch_signing_key: mocked_fetch_signing_key_always_succeed + authentication_parameters: authentication_parameters_with_valid_token ) end From 2049cee41547c560d8e6df60e459c3e007eac854 Mon Sep 17 00:00:00 2001 From: Nessi Lahav Date: Mon, 9 Aug 2021 15:07:28 +0300 Subject: [PATCH 3/5] Bugfix status cache (#2356) * ONYX-11330: Fix cache of signing key * Fix cache bug in authn-jwt status flow * Fixes according to PR comments Co-authored-by: Tamir Zheleznyak --- .../authn_jwt/validate_status.rb | 34 +++++++++---------- .../features/authn_status_jwt.feature | 11 +++--- .../authn-jwt/validate_status_spec.rb | 28 ++++++++++++--- 3 files changed, 48 insertions(+), 25 deletions(-) diff --git a/app/domain/authentication/authn_jwt/validate_status.rb b/app/domain/authentication/authn_jwt/validate_status.rb index bea09ec60f..e9ca7a07f9 100644 --- a/app/domain/authentication/authn_jwt/validate_status.rb +++ b/app/domain/authentication/authn_jwt/validate_status.rb @@ -3,6 +3,16 @@ module AuthnJwt ValidateStatus = CommandClass.new( dependencies: { + fetch_signing_key_from_cache: ::Util::ConcurrencyLimitedCache.new( + ::Util::RateLimitedCache.new( + ::Authentication::AuthnJwt::SigningKey::FetchCachedSigningKey.new, + refreshes_per_interval: CACHE_REFRESHES_PER_INTERVAL, + rate_limit_interval: CACHE_RATE_LIMIT_INTERVAL, + logger: Rails.logger + ), + max_concurrent_requests: CACHE_MAX_CONCURRENT_REQUESTS, + logger: Rails.logger + ), create_signing_key_interface: Authentication::AuthnJwt::SigningKey::CreateSigningKeyFactory.new, fetch_issuer_value: Authentication::AuthnJwt::ValidateAndDecode::FetchIssuerValue.new, fetch_audience_value: Authentication::AuthnJwt::ValidateAndDecode::FetchAudienceValue.new, @@ -134,25 +144,15 @@ def webservice end def validate_signing_key - fetch_signing_key.call - @logger.debug(LogMessages::Authentication::AuthnJwt::ValidatedSigningKeyConfiguration.new) - end - - def fetch_signing_key - @fetch_signing_key ||= ::Util::ConcurrencyLimitedCache.new( - ::Util::RateLimitedCache.new( - fetch_signing_key_interface, - refreshes_per_interval: ::Authentication::AuthnJwt::CACHE_REFRESHES_PER_INTERVAL, - rate_limit_interval: ::Authentication::AuthnJwt::CACHE_RATE_LIMIT_INTERVAL, - logger: @logger - ), - max_concurrent_requests: ::Authentication::AuthnJwt::CACHE_MAX_CONCURRENT_REQUESTS, - logger: @logger + @fetch_signing_key_from_cache.call( + cache_key: signing_key_interface.signing_key_uri, + signing_key_interface: signing_key_interface ) + @logger.debug(LogMessages::Authentication::AuthnJwt::ValidatedSigningKeyConfiguration.new) end - - def fetch_signing_key_interface - @fetch_signing_key_interface ||= @create_signing_key_interface.call( + + def signing_key_interface + @signing_key_interface ||= @create_signing_key_interface.call( authentication_parameters: authentication_parameters ) end diff --git a/cucumber/authenticators_jwt/features/authn_status_jwt.feature b/cucumber/authenticators_jwt/features/authn_status_jwt.feature index ec764f41e0..8ee89ffcfa 100644 --- a/cucumber/authenticators_jwt/features/authn_status_jwt.feature +++ b/cucumber/authenticators_jwt/features/authn_status_jwt.feature @@ -3,6 +3,9 @@ Feature: JWT Authenticator - Status Check Checks status API of JWT authenticator. Status API should return error on each case of misconfiguration in authenticator or policy that can be found before authentication request. + Background: + Given I initialize remote JWKS endpoint with file "authn-jwt-configuration" and alg "RS256" + @sanity Scenario: ONYX-9122: A valid JWT status request, 200 OK Given I load a policy: @@ -56,7 +59,7 @@ Feature: JWT Authenticator - Status Check - !user alice """ And I am the super-user - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-configuration/RS256" in service "raw" And I successfully set authn-jwt "token-app-property" variable to value "user" And I successfully set authn-jwt "issuer" variable to value "gitlab" And I successfully set authn-jwt "audience" variable to value "conjur" @@ -278,7 +281,7 @@ Feature: JWT Authenticator - Status Check - !user alice """ And I am the super-user - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-configuration/RS256" in service "raw" And I successfully set authn-jwt "token-app-property" variable to value "user" And I login as "alice" And I save my place in the log file @@ -764,7 +767,7 @@ Feature: JWT Authenticator - Status Check - !user alice """ And I am the super-user - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-configuration/RS256" in service "raw" And I successfully set authn-jwt "token-app-property" variable to value "user" And I successfully set authn-jwt "identity-path" variable to value "apps" And I successfully set authn-jwt "issuer" variable to value "gitlab" @@ -832,7 +835,7 @@ Feature: JWT Authenticator - Status Check - !user alice """ And I am the super-user - And I successfully set authn-jwt jwks-uri variable with value of "myJWKs.json" endpoint + And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-configuration/RS256" in service "raw" And I successfully set authn-jwt "token-app-property" variable to value "user" And I successfully set authn-jwt "mapping-claims" variable to value "branch:ref" And I successfully set authn-jwt "enforced-claims" variable to value "ref" diff --git a/spec/app/domain/authentication/authn-jwt/validate_status_spec.rb b/spec/app/domain/authentication/authn-jwt/validate_status_spec.rb index 375124cae4..25e6fa434c 100644 --- a/spec/app/domain/authentication/authn-jwt/validate_status_spec.rb +++ b/spec/app/domain/authentication/authn-jwt/validate_status_spec.rb @@ -7,6 +7,8 @@ let(:authenticator_name) { 'authn-jwt' } let(:service_id) { "my-service" } let(:account) { 'my-account' } + let(:valid_signing_key_uri) { 'valid-signing-key-uri' } + let(:valid_signing_key) { 'valid-signing-key' } let(:authenticator_status_input) { Authentication::AuthenticatorStatusInput.new( @@ -52,15 +54,21 @@ let(:user_cant_access_webservice_error) { "User cant access webservice" } let(:webservice_does_not_exist_error) { "Webservice does not exist" } let(:account_does_not_exist_error) { "Account does not exist" } - let(:mocked_valid_fetch_signing_key_interface) { double("Mocked valid fetch signing key interface") } + let(:mocked_valid_signing_key_interface) { double("Mocked valid signing key interface") } + let(:mocked_valid_fetch_signing_key_from_cache) { double("Mocked valid fetch signing key interface") } + before(:each) do allow(mocked_valid_create_signing_key_interface).to( - receive(:call).and_return(mocked_valid_fetch_signing_key_interface) + receive(:call).and_return(mocked_valid_signing_key_interface) ) - allow(mocked_valid_fetch_signing_key_interface).to( - receive(:call).and_return(nil) + allow(mocked_valid_signing_key_interface).to( + receive(:signing_key_uri).and_return(valid_signing_key_uri) + ) + + allow(mocked_valid_fetch_signing_key_from_cache).to( + receive(:call).and_return(valid_signing_key) ) allow(mocked_invalid_create_signing_key_interface).to( @@ -158,6 +166,7 @@ subject do ::Authentication::AuthnJwt::ValidateStatus.new( + fetch_signing_key_from_cache: mocked_valid_fetch_signing_key_from_cache, create_signing_key_interface: mocked_valid_create_signing_key_interface, fetch_issuer_value: mocked_valid_fetch_issuer_value, identity_from_decoded_token_provider_class: mocked_valid_identity_from_decoded_token_provider, @@ -182,6 +191,7 @@ subject do ::Authentication::AuthnJwt::ValidateStatus.new( + fetch_signing_key_from_cache: mocked_valid_fetch_signing_key_from_cache, create_signing_key_interface: mocked_valid_create_signing_key_interface, fetch_issuer_value: mocked_valid_fetch_issuer_value, identity_from_decoded_token_provider_class: mocked_valid_identity_from_decoded_token_provider, @@ -205,6 +215,7 @@ subject do ::Authentication::AuthnJwt::ValidateStatus.new( + fetch_signing_key_from_cache: mocked_valid_fetch_signing_key_from_cache, create_signing_key_interface: mocked_valid_create_signing_key_interface, fetch_issuer_value: mocked_valid_fetch_issuer_value, identity_from_decoded_token_provider_class: mocked_valid_identity_from_decoded_token_provider, @@ -228,6 +239,7 @@ subject do ::Authentication::AuthnJwt::ValidateStatus.new( + fetch_signing_key_from_cache: mocked_valid_fetch_signing_key_from_cache, create_signing_key_interface: mocked_valid_create_signing_key_interface, fetch_issuer_value: mocked_valid_fetch_issuer_value, identity_from_decoded_token_provider_class: mocked_valid_identity_from_decoded_token_provider, @@ -251,6 +263,7 @@ subject do ::Authentication::AuthnJwt::ValidateStatus.new( + fetch_signing_key_from_cache: mocked_valid_fetch_signing_key_from_cache, create_signing_key_interface: mocked_valid_create_signing_key_interface, fetch_issuer_value: mocked_valid_fetch_issuer_value, identity_from_decoded_token_provider_class: mocked_valid_identity_from_decoded_token_provider, @@ -286,6 +299,7 @@ subject do ::Authentication::AuthnJwt::ValidateStatus.new( + fetch_signing_key_from_cache: mocked_valid_fetch_signing_key_from_cache, create_signing_key_interface: mocked_valid_create_signing_key_interface, fetch_issuer_value: mocked_valid_fetch_issuer_value, identity_from_decoded_token_provider_class: mocked_valid_identity_from_decoded_token_provider, @@ -310,6 +324,7 @@ context "signing key secrets are not configured properly" do subject do ::Authentication::AuthnJwt::ValidateStatus.new( + fetch_signing_key_from_cache: mocked_valid_fetch_signing_key_from_cache, create_signing_key_interface: mocked_invalid_create_signing_key_interface, fetch_issuer_value: mocked_valid_fetch_issuer_value, identity_from_decoded_token_provider_class: mocked_valid_identity_from_decoded_token_provider, @@ -332,6 +347,7 @@ context "issuer secrets are not configured properly" do subject do ::Authentication::AuthnJwt::ValidateStatus.new( + fetch_signing_key_from_cache: mocked_valid_fetch_signing_key_from_cache, create_signing_key_interface: mocked_valid_create_signing_key_interface, fetch_issuer_value: mocked_invalid_fetch_issuer_value, identity_from_decoded_token_provider_class: mocked_valid_identity_from_decoded_token_provider, @@ -354,6 +370,7 @@ context "audience secret is not configured properly" do subject do ::Authentication::AuthnJwt::ValidateStatus.new( + fetch_signing_key_from_cache: mocked_valid_fetch_signing_key_from_cache, create_signing_key_interface: mocked_valid_create_signing_key_interface, fetch_issuer_value: mocked_valid_fetch_issuer_value, fetch_audience_value: mocked_invalid_fetch_audience_value, @@ -377,6 +394,7 @@ context "enforced claims is not configured properly" do subject do ::Authentication::AuthnJwt::ValidateStatus.new( + fetch_signing_key_from_cache: mocked_valid_fetch_signing_key_from_cache, create_signing_key_interface: mocked_valid_create_signing_key_interface, fetch_issuer_value: mocked_valid_fetch_issuer_value, fetch_enforced_claims: mocked_invalid_fetch_enforced_claims, @@ -400,6 +418,7 @@ context "mapping claims is not configured properly" do subject do ::Authentication::AuthnJwt::ValidateStatus.new( + fetch_signing_key_from_cache: mocked_valid_fetch_signing_key_from_cache, create_signing_key_interface: mocked_valid_create_signing_key_interface, fetch_issuer_value: mocked_valid_fetch_issuer_value, fetch_mapping_claims: mocked_invalid_fetch_mapping_claims, @@ -423,6 +442,7 @@ context "identity secrets are not configured properly" do subject do ::Authentication::AuthnJwt::ValidateStatus.new( + fetch_signing_key_from_cache: mocked_valid_fetch_signing_key_from_cache, create_signing_key_interface: mocked_valid_create_signing_key_interface, fetch_issuer_value: mocked_valid_fetch_issuer_value, identity_from_decoded_token_provider_class: mocked_invalid_identity_from_decoded_token_provider, From 7cebf4a9edeb4d1aad4642272ec4e68e35a3fc8f Mon Sep 17 00:00:00 2001 From: Sasha Chernomordik Date: Mon, 9 Aug 2021 15:15:12 +0300 Subject: [PATCH 4/5] Fix signing_key UTs --- .../authn-jwt/signing_key/fetch_jwks_signing_key_spec.rb | 6 +++--- .../signing_key/fetch_provider_uri_signing_key_spec.rb | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/app/domain/authentication/authn-jwt/signing_key/fetch_jwks_signing_key_spec.rb b/spec/app/domain/authentication/authn-jwt/signing_key/fetch_jwks_signing_key_spec.rb index 9826f560f3..8ae4f51f3f 100644 --- a/spec/app/domain/authentication/authn-jwt/signing_key/fetch_jwks_signing_key_spec.rb +++ b/spec/app/domain/authentication/authn-jwt/signing_key/fetch_jwks_signing_key_spec.rb @@ -129,7 +129,7 @@ resource_class: mocked_resource_value_exists, http_lib: mocked_bad_http_response, create_jwks_from_http_response: mocked_create_jwks_from_http_response - ).call + ).fetch_signing_key end it "raises an error" do @@ -146,7 +146,7 @@ resource_class: mocked_resource_value_exists, http_lib: mocked_good_http_response, create_jwks_from_http_response: mocked_create_jwks_from_http_response - ).call + ).fetch_signing_key end it "returns jwks value" do @@ -162,7 +162,7 @@ resource_class: mocked_resource_value_exists, http_lib: mocked_bad_http_response, create_jwks_from_http_response: mocked_create_jwks_from_http_response - ).call + ).fetch_signing_key end it "raises an error" do diff --git a/spec/app/domain/authentication/authn-jwt/signing_key/fetch_provider_uri_signing_key_spec.rb b/spec/app/domain/authentication/authn-jwt/signing_key/fetch_provider_uri_signing_key_spec.rb index 3f6bde821d..c4f734e8ae 100644 --- a/spec/app/domain/authentication/authn-jwt/signing_key/fetch_provider_uri_signing_key_spec.rb +++ b/spec/app/domain/authentication/authn-jwt/signing_key/fetch_provider_uri_signing_key_spec.rb @@ -117,7 +117,7 @@ logger: mocked_logger, fetch_required_secrets: mocked_fetch_required_existing_secret, resource_class: mocked_resource_value_exists, - discover_identity_provider: mocked_invalid_uri_discover_identity_provider).call + discover_identity_provider: mocked_invalid_uri_discover_identity_provider).fetch_signing_key end it "raises an error" do @@ -131,7 +131,7 @@ logger: mocked_logger, fetch_required_secrets: mocked_fetch_required_existing_secret, resource_class: mocked_resource_value_exists, - discover_identity_provider: mocked_discover_identity_provider).call + discover_identity_provider: mocked_discover_identity_provider).fetch_signing_key end it "does not raise error" do From 346f9d5d5de699000ec2b066895f18ebb15516f6 Mon Sep 17 00:00:00 2001 From: Tamir Zheleznyak Date: Mon, 9 Aug 2021 17:14:53 +0300 Subject: [PATCH 5/5] Fix by PR comments --- CHANGELOG.md | 3 + ...tory.rb => create_signing_key_provider.rb} | 6 +- .../signing_key/fetch_cached_signing_key.rb | 14 ++- .../validate_and_decode_token.rb | 16 ++- .../authn_jwt/validate_status.rb | 14 +-- .../configuration_jwt_generic_vendor.rb | 16 --- app/domain/util/concurrency_limited_cache.rb | 19 ++-- app/domain/util/rate_limited_cache.rb | 14 +-- .../authn_jwt_fetch_signing_key.feature | 54 +--------- ...rb => create_signing_key_provider_spec.rb} | 12 +-- .../validate_and_decode_token_spec.rb | 102 +++++++++--------- .../authn-jwt/validate_status_spec.rb | 66 ++++++------ 12 files changed, 136 insertions(+), 200 deletions(-) rename app/domain/authentication/authn_jwt/signing_key/{create_signing_key_factory.rb => create_signing_key_provider.rb} (95%) rename spec/app/domain/authentication/authn-jwt/signing_key/{create_signing_key_factory_spec.rb => create_signing_key_provider_spec.rb} (97%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 55378e5c70..c7d611624b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +### Fixed +- Fix bug of cache not working in authn jwt. [ONYX-11330](https://ca-il-jira.il.cyber-ark.com:8443/browse/ONYX-11330) + ## [1.13.0] - 2021-07-29 ### Added diff --git a/app/domain/authentication/authn_jwt/signing_key/create_signing_key_factory.rb b/app/domain/authentication/authn_jwt/signing_key/create_signing_key_provider.rb similarity index 95% rename from app/domain/authentication/authn_jwt/signing_key/create_signing_key_factory.rb rename to app/domain/authentication/authn_jwt/signing_key/create_signing_key_provider.rb index ac0f0e4850..08d95b3f46 100644 --- a/app/domain/authentication/authn_jwt/signing_key/create_signing_key_factory.rb +++ b/app/domain/authentication/authn_jwt/signing_key/create_signing_key_provider.rb @@ -2,7 +2,7 @@ module Authentication module AuthnJwt module SigningKey # Factory that returns the interface implementation of FetchSigningKey - CreateSigningKeyFactory ||= CommandClass.new( + CreateSigningKeyProvider ||= CommandClass.new( dependencies: { fetch_provider_uri_signing_key_class: Authentication::AuthnJwt::SigningKey::FetchProviderUriSigningKey, fetch_jwks_uri_signing_key_class: Authentication::AuthnJwt::SigningKey::FetchJwksUriSigningKey, @@ -13,12 +13,12 @@ module SigningKey def call @logger.debug(LogMessages::Authentication::AuthnJwt::SelectingSigningKeyInterface.new) validate_key_configuration - create_signing_key + create_signing_key_provider end private - def create_signing_key + def create_signing_key_provider if provider_uri_has_valid_configuration? @logger.info( LogMessages::Authentication::AuthnJwt::SelectedSigningKeyInterface.new(PROVIDER_URI_INTERFACE_NAME) diff --git a/app/domain/authentication/authn_jwt/signing_key/fetch_cached_signing_key.rb b/app/domain/authentication/authn_jwt/signing_key/fetch_cached_signing_key.rb index 2d916585aa..8596e29ac6 100644 --- a/app/domain/authentication/authn_jwt/signing_key/fetch_cached_signing_key.rb +++ b/app/domain/authentication/authn_jwt/signing_key/fetch_cached_signing_key.rb @@ -6,20 +6,18 @@ module SigningKey # fetch_signing_key it is extreme case that error need to be raised so it can be investigated so reek will ignore # this. # :reek:InstanceVariableAssumption - class FetchCachedSigningKey - def initialize(logger: Rails.logger) - @logger = logger - end - - def call(signing_key_interface:) - @signing_key_interface = signing_key_interface + FetchCachedSigningKey = CommandClass.new( + dependencies: {}, + inputs: %i[signing_key_provider] + ) do + def call fetch_signing_key end private def fetch_signing_key - @signing_key_interface.fetch_signing_key + @signing_key_provider.fetch_signing_key end end end diff --git a/app/domain/authentication/authn_jwt/validate_and_decode/validate_and_decode_token.rb b/app/domain/authentication/authn_jwt/validate_and_decode/validate_and_decode_token.rb index b177a36072..5ac7365995 100644 --- a/app/domain/authentication/authn_jwt/validate_and_decode/validate_and_decode_token.rb +++ b/app/domain/authentication/authn_jwt/validate_and_decode/validate_and_decode_token.rb @@ -7,7 +7,7 @@ module ValidateAndDecode # for the 2nd validation ValidateAndDecodeToken ||= CommandClass.new( dependencies: { - fetch_signing_key_from_cache: ::Util::ConcurrencyLimitedCache.new( + fetch_signing_key: ::Util::ConcurrencyLimitedCache.new( ::Util::RateLimitedCache.new( ::Authentication::AuthnJwt::SigningKey::FetchCachedSigningKey.new, refreshes_per_interval: CACHE_REFRESHES_PER_INTERVAL, @@ -20,7 +20,7 @@ module ValidateAndDecode verify_and_decode_token: ::Authentication::Jwt::VerifyAndDecodeToken.new, fetch_jwt_claims_to_validate: ::Authentication::AuthnJwt::ValidateAndDecode::FetchJwtClaimsToValidate.new, get_verification_option_by_jwt_claim: ::Authentication::AuthnJwt::ValidateAndDecode::GetVerificationOptionByJwtClaim.new, - signing_key_interface_factory: ::Authentication::AuthnJwt::SigningKey::CreateSigningKeyFactory.new, + create_signing_key_provider: ::Authentication::AuthnJwt::SigningKey::CreateSigningKeyProvider.new, logger: Rails.logger }, inputs: %i[authentication_parameters] @@ -31,7 +31,6 @@ module ValidateAndDecode def call @logger.debug(LogMessages::Authentication::AuthnJwt::ValidatingToken.new) validate_token_exists - fetch_signing_key_interface fetch_signing_key validate_signature fetch_jwt_claims_to_validate @@ -43,9 +42,8 @@ def call private - # Don't do memoization here because otherwise interface won't change between different requests - def fetch_signing_key_interface - @signing_key_interface = @signing_key_interface_factory.call( + def signing_key_provider + @signing_key_provider ||= @create_signing_key_provider.call( authentication_parameters: @authentication_parameters ) end @@ -55,10 +53,10 @@ def validate_token_exists end def fetch_signing_key(force_read: false) - @jwks = @fetch_signing_key_from_cache.call( + @jwks = @fetch_signing_key.call( refresh: force_read, - cache_key: @signing_key_interface.signing_key_uri, - signing_key_interface: @signing_key_interface + cache_key: signing_key_provider.signing_key_uri, + signing_key_provider: signing_key_provider ) @logger.debug(LogMessages::Authentication::AuthnJwt::SigningKeysFetchedFromCache.new) end diff --git a/app/domain/authentication/authn_jwt/validate_status.rb b/app/domain/authentication/authn_jwt/validate_status.rb index e9ca7a07f9..8fe377a756 100644 --- a/app/domain/authentication/authn_jwt/validate_status.rb +++ b/app/domain/authentication/authn_jwt/validate_status.rb @@ -3,7 +3,7 @@ module AuthnJwt ValidateStatus = CommandClass.new( dependencies: { - fetch_signing_key_from_cache: ::Util::ConcurrencyLimitedCache.new( + fetch_signing_key: ::Util::ConcurrencyLimitedCache.new( ::Util::RateLimitedCache.new( ::Authentication::AuthnJwt::SigningKey::FetchCachedSigningKey.new, refreshes_per_interval: CACHE_REFRESHES_PER_INTERVAL, @@ -13,7 +13,7 @@ module AuthnJwt max_concurrent_requests: CACHE_MAX_CONCURRENT_REQUESTS, logger: Rails.logger ), - create_signing_key_interface: Authentication::AuthnJwt::SigningKey::CreateSigningKeyFactory.new, + create_signing_key_provider: Authentication::AuthnJwt::SigningKey::CreateSigningKeyProvider.new, fetch_issuer_value: Authentication::AuthnJwt::ValidateAndDecode::FetchIssuerValue.new, fetch_audience_value: Authentication::AuthnJwt::ValidateAndDecode::FetchAudienceValue.new, fetch_enforced_claims: Authentication::AuthnJwt::RestrictionValidation::FetchEnforcedClaims.new, @@ -144,15 +144,15 @@ def webservice end def validate_signing_key - @fetch_signing_key_from_cache.call( - cache_key: signing_key_interface.signing_key_uri, - signing_key_interface: signing_key_interface + @fetch_signing_key.call( + cache_key: signing_key_provider.signing_key_uri, + signing_key_provider: signing_key_provider ) @logger.debug(LogMessages::Authentication::AuthnJwt::ValidatedSigningKeyConfiguration.new) end - def signing_key_interface - @signing_key_interface ||= @create_signing_key_interface.call( + def signing_key_provider + @signing_key_provider ||= @create_signing_key_provider.call( authentication_parameters: authentication_parameters ) end diff --git a/app/domain/authentication/authn_jwt/vendor_configurations/configuration_jwt_generic_vendor.rb b/app/domain/authentication/authn_jwt/vendor_configurations/configuration_jwt_generic_vendor.rb index b75e2b547d..ba0cb9f257 100644 --- a/app/domain/authentication/authn_jwt/vendor_configurations/configuration_jwt_generic_vendor.rb +++ b/app/domain/authentication/authn_jwt/vendor_configurations/configuration_jwt_generic_vendor.rb @@ -82,12 +82,6 @@ def identity_provider ) end - def fetch_singing_key_interface - @fetch_singing_key_interface ||= create_signing_key_interface.call( - authentication_parameters: @authentication_parameters - ) - end - def create_identity_provider @logger.debug(LogMessages::Authentication::AuthnJwt::CreateJwtIdentityProviderInstance.new) @create_identity_provider ||= @create_identity_provider @@ -95,16 +89,6 @@ def create_identity_provider @create_identity_provider end - def fetch_signing_key_interface - @fetch_signing_key_interface ||= create_signing_key_interface.call( - authentication_parameters: @authentication_parameters - ) - end - - def create_signing_key_interface - @create_signing_key_interface ||= Authentication::AuthnJwt::SigningKey::CreateSigningKeyFactory.new - end - def restrictions_from_annotations @restrictions_from_annotations ||= Authentication::ResourceRestrictions::GetServiceSpecificRestrictionFromAnnotation.new end diff --git a/app/domain/util/concurrency_limited_cache.rb b/app/domain/util/concurrency_limited_cache.rb index ffc2676323..6fbff88d3c 100644 --- a/app/domain/util/concurrency_limited_cache.rb +++ b/app/domain/util/concurrency_limited_cache.rb @@ -25,7 +25,7 @@ def initialize( # not in case before the flow runs and it can cause unexpected behaviour so reek will ignore this. # reek:DuplicateMethodCall def call(**args) - cache_key = cached_key(args) + cache_key = cache_key(args) @concurrency_mutex.synchronize do if @concurrent_requests >= @max_concurrent_requests @logger.debug( @@ -72,13 +72,18 @@ def decrease_concurrent_requests end end - def cached_key(args) - cache_key = args.key?(:cache_key) ? args.fetch(:cache_key) : args - @logger.debug( - LogMessages::Util::ConcurrencyLimitedCacheKeyRetrieved.new( - cache_key + # Function returning cache key to store/retrieve in the cache + def cache_key(args) + if args.key?(:cache_key) + cache_key = args.fetch(:cache_key) + @logger.debug( + LogMessages::Util::ConcurrencyLimitedCacheKeyRetrieved.new( + cache_key + ) ) - ) + else + cache_key = args + end cache_key end end diff --git a/app/domain/util/rate_limited_cache.rb b/app/domain/util/rate_limited_cache.rb index 4e43919278..befa064dae 100644 --- a/app/domain/util/rate_limited_cache.rb +++ b/app/domain/util/rate_limited_cache.rb @@ -72,14 +72,14 @@ def cached_key(args) if args.key?(:cache_key) cache_key = args.fetch(:cache_key) args.delete(:cache_key) - cache_key - end - cache_key = args - @logger.debug( - LogMessages::Util::RateLimitedCacheKeyRetrieved.new( - cache_key + @logger.debug( + LogMessages::Util::RateLimitedCacheKeyRetrieved.new( + cache_key + ) ) - ) + else + cache_key = args + end cache_key end diff --git a/cucumber/authenticators_jwt/features/authn_jwt_fetch_signing_key.feature b/cucumber/authenticators_jwt/features/authn_jwt_fetch_signing_key.feature index 79a49b3b58..700ef18fda 100644 --- a/cucumber/authenticators_jwt/features/authn_jwt_fetch_signing_key.feature +++ b/cucumber/authenticators_jwt/features/authn_jwt_fetch_signing_key.feature @@ -3,6 +3,7 @@ Feature: JWT Authenticator - Fetch signing key In this feature we define a JWT authenticator with various signing key configurations. + @sanity Scenario: ONYX-8702: provider-uri is configured with valid value Given I load a policy: """ @@ -88,59 +89,6 @@ Feature: JWT Authenticator - Fetch signing key CONJ00011E Failed to discover Identity Provider (Provider URI: 'unknown-host.com') """ - Scenario: ONYX-8703: jwks uri configured with correct value - Given I load a policy: - """ - - !policy - id: conjur/authn-jwt/raw - body: - - !webservice - - - !variable - id: jwks-uri - - - !variable - id: token-app-property - - - !group hosts - - - !permit - role: !group hosts - privilege: [ read, authenticate ] - resource: !webservice - - - !host - id: myapp - annotations: - authn-jwt/raw/project-id: myproject - - - !grant - role: !group conjur/authn-jwt/raw/hosts - member: !host myapp - """ - And I am the super-user - And I initialize remote JWKS endpoint with file "authn-jwt-fetch-signing-key" and alg "RS256" - And I successfully set authn-jwt "jwks-uri" variable value to "http://jwks_py:8090/authn-jwt-fetch-signing-key/RS256" in service "raw" - And I have a "variable" resource called "test-variable" - And I successfully set authn-jwt "token-app-property" variable to value "host" - And I permit host "myapp" to "execute" it - And I add the secret value "test-secret" to the resource "cucumber:variable:test-variable" - And I am using file "authn-jwt-fetch-signing-key" and alg "RS256" for remotely issue token: - """ - { - "host":"myapp", - "project-id": "myproject" - } - """ - And I save my place in the log file - When I authenticate via authn-jwt with the JWT token - Then host "myapp" has been authorized by Conjur - And I successfully GET "/secrets/cucumber/variable/test-variable" with authorized user - And The following appears in the log after my savepoint: - """ - cucumber:host:myapp successfully authenticated with authenticator authn-jwt service cucumber:webservice:conjur/authn-jwt/raw - """ - Scenario: ONYX-8705: jwks uri configured with bad value Given I load a policy: """ diff --git a/spec/app/domain/authentication/authn-jwt/signing_key/create_signing_key_factory_spec.rb b/spec/app/domain/authentication/authn-jwt/signing_key/create_signing_key_provider_spec.rb similarity index 97% rename from spec/app/domain/authentication/authn-jwt/signing_key/create_signing_key_factory_spec.rb rename to spec/app/domain/authentication/authn-jwt/signing_key/create_signing_key_provider_spec.rb index 3eed59f336..0ee8609153 100644 --- a/spec/app/domain/authentication/authn-jwt/signing_key/create_signing_key_factory_spec.rb +++ b/spec/app/domain/authentication/authn-jwt/signing_key/create_signing_key_provider_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe('Authentication::AuthnJwt::SigningKey::CreateSigningKeyInterface') do +RSpec.describe('Authentication::AuthnJwt::SigningKey::CreateSigningKeyProvider') do let(:authenticator_name) { 'authn-jwt' } let(:service_id) { "my-service" } @@ -70,11 +70,11 @@ # )( ) _ ( )__) )( )__) \__ \ )( \__ \ # (__) (_) (_)(____) (__) (____)(___/ (__) (___/ - context "CreateSigningKeyInterface " do + context "CreateSigningKeyProvider " do context "'jwks-uri' and 'provider-uri' exist" do subject do - ::Authentication::AuthnJwt::SigningKey::CreateSigningKeyFactory.new( + ::Authentication::AuthnJwt::SigningKey::CreateSigningKeyProvider.new( fetch_provider_uri_signing_key_class: mocked_fetch_exists_provider_uri, fetch_jwks_uri_signing_key_class: mocked_fetch_exists_jwks_uri, logger: mocked_logger @@ -91,7 +91,7 @@ context "'jwks-uri' and 'provider-uri' does not exist" do subject do - ::Authentication::AuthnJwt::SigningKey::CreateSigningKeyFactory.new( + ::Authentication::AuthnJwt::SigningKey::CreateSigningKeyProvider.new( fetch_provider_uri_signing_key_class: mocked_fetch_non_exists_provider_uri, fetch_jwks_uri_signing_key_class: mocked_fetch_non_exists_jwks_uri, logger: mocked_logger @@ -108,7 +108,7 @@ context "'jwks-uri' exits and 'provider-uri' does not exists" do subject do - ::Authentication::AuthnJwt::SigningKey::CreateSigningKeyFactory.new( + ::Authentication::AuthnJwt::SigningKey::CreateSigningKeyProvider.new( fetch_provider_uri_signing_key_class: mocked_fetch_non_exists_provider_uri, fetch_jwks_uri_signing_key_class: mocked_fetch_exists_jwks_uri, logger: mocked_logger @@ -125,7 +125,7 @@ context "'jwks-uri' does not exists and 'provider-uri' exist" do subject do - ::Authentication::AuthnJwt::SigningKey::CreateSigningKeyFactory.new( + ::Authentication::AuthnJwt::SigningKey::CreateSigningKeyProvider.new( fetch_provider_uri_signing_key_class: mocked_fetch_exists_provider_uri, fetch_jwks_uri_signing_key_class: mocked_fetch_non_exists_jwks_uri, logger: mocked_logger diff --git a/spec/app/domain/authentication/authn-jwt/validate_and_decode/validate_and_decode_token_spec.rb b/spec/app/domain/authentication/authn-jwt/validate_and_decode/validate_and_decode_token_spec.rb index 9642918ed4..67e25cec4a 100644 --- a/spec/app/domain/authentication/authn-jwt/validate_and_decode/validate_and_decode_token_spec.rb +++ b/spec/app/domain/authentication/authn-jwt/validate_and_decode/validate_and_decode_token_spec.rb @@ -45,16 +45,16 @@ ) } - let(:mocked_signing_key_interface_factory_valid) { double("MockedSigningKeyInterfaceFactoryValid") } - let(:mocked_signing_key_interface_factory_invalid) { double("MockedSigningKeyInterfaceFactoryInvalid") } - let(:mocked_signing_key_interface_factory_failed) { double("MockedSigningKeyInterfaceFactoryFailed") } + let(:mocked_create_signing_key_provider_valid) { double("MockedSigningKeyInterfaceFactoryValid") } + let(:mocked_create_signing_key_provider_invalid) { double("MockedSigningKeyInterfaceFactoryInvalid") } + let(:mocked_create_signing_key_provider_failed) { double("MockedSigningKeyInterfaceFactoryFailed") } - let(:signing_key_interface_factory_error) { "signing key interface factory error" } + let(:create_signing_key_provider_error) { "signing key interface factory error" } - let(:mocked_fetch_signing_key_interface_valid) { double("MockedSigningKeyInterfaceValid") } - let(:mocked_fetch_signing_key_interface_failed) { double("MockedSigningKeyInterfaceFailed") } + let(:mocked_fetch_signing_key_provider_valid) { double("MockedSigningKeyInterfaceValid") } + let(:mocked_fetch_signing_key_provider_failed) { double("MockedSigningKeyInterfaceFailed") } - let(:fetch_signing_key_interface_error) { "fetch signing key interface error" } + let(:fetch_signing_key_provider_error) { "fetch signing key interface error" } let(:mocked_fetch_signing_key_failed_on_1st_time) { double("MockedFetchSigningKeyInvalid") } let(:mocked_fetch_signing_key_failed_on_2nd_time) { double("MockedFetchSigningKeyInvalid") } @@ -136,31 +136,31 @@ def valid_decoded_token(claims) let(:mocked_verify_and_decode_token_succeed_to_validate_claims_when_keys_updated) { double("MockedVerifyAndDecodeTokenSucceedToValidateClaims") } before(:each) do - allow(mocked_fetch_signing_key_interface_valid).to( + allow(mocked_fetch_signing_key_provider_valid).to( receive(:signing_key_uri).and_return(valid_signing_key_uri) ) - allow(mocked_signing_key_interface_factory_valid).to( - receive(:call).and_return(mocked_fetch_signing_key_interface_valid) + allow(mocked_create_signing_key_provider_valid).to( + receive(:call).and_return(mocked_fetch_signing_key_provider_valid) ) - allow(mocked_fetch_signing_key_interface_failed).to( - receive(:signing_key_uri).and_raise(fetch_signing_key_interface_error) + allow(mocked_fetch_signing_key_provider_failed).to( + receive(:signing_key_uri).and_raise(fetch_signing_key_provider_error) ) - allow(mocked_signing_key_interface_factory_invalid).to( - receive(:call).and_return(mocked_fetch_signing_key_interface_failed) + allow(mocked_create_signing_key_provider_invalid).to( + receive(:call).and_return(mocked_fetch_signing_key_provider_failed) ) - allow(mocked_signing_key_interface_factory_failed).to( - receive(:call).and_raise(signing_key_interface_factory_error) + allow(mocked_create_signing_key_provider_failed).to( + receive(:call).and_raise(create_signing_key_provider_error) ) allow(mocked_fetch_signing_key_failed_on_1st_time).to( receive(:call).with( refresh: false, cache_key: anything(), - signing_key_interface: anything() + signing_key_provider: anything() ).and_raise(fetch_signing_key_1st_time_error) ) @@ -168,7 +168,7 @@ def valid_decoded_token(claims) receive(:call).with( refresh: false, cache_key: anything(), - signing_key_interface: anything() + signing_key_provider: anything() ).and_return(jwks_from_2nd_call) ) @@ -176,7 +176,7 @@ def valid_decoded_token(claims) receive(:call).with( refresh: true, cache_key: anything(), - signing_key_interface: anything() + signing_key_provider: anything() ).and_raise(fetch_signing_key_2nd_time_error) ) @@ -188,7 +188,7 @@ def valid_decoded_token(claims) receive(:call).with( refresh: false, cache_key: anything(), - signing_key_interface: anything() + signing_key_provider: anything() ).and_return(jwks_from_1st_call) ) @@ -196,7 +196,7 @@ def valid_decoded_token(claims) receive(:call).with( refresh: true, cache_key: anything(), - signing_key_interface: anything() + signing_key_provider: anything() ).and_return(jwks_from_2nd_call) ) @@ -345,38 +345,38 @@ def valid_decoded_token(claims) context "When error is during signing key factory call" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( - fetch_signing_key_from_cache: mocked_fetch_signing_key_failed_on_1st_time, - signing_key_interface_factory: mocked_signing_key_interface_factory_failed + fetch_signing_key: mocked_fetch_signing_key_failed_on_1st_time, + create_signing_key_provider: mocked_create_signing_key_provider_failed ).call( authentication_parameters: authentication_parameters_with_valid_token ) end it "raises an error" do - expect { subject }.to raise_error(signing_key_interface_factory_error) + expect { subject }.to raise_error(create_signing_key_provider_error) end end context "When error is during signing_key_uri call" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( - fetch_signing_key_from_cache: mocked_fetch_signing_key_failed_on_1st_time, - signing_key_interface_factory: mocked_signing_key_interface_factory_invalid + fetch_signing_key: mocked_fetch_signing_key_failed_on_1st_time, + create_signing_key_provider: mocked_create_signing_key_provider_invalid ).call( authentication_parameters: authentication_parameters_with_valid_token ) end it "raises an error" do - expect { subject }.to raise_error(fetch_signing_key_interface_error) + expect { subject }.to raise_error(fetch_signing_key_provider_error) end end context "When error is during fetching from cache" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( - fetch_signing_key_from_cache: mocked_fetch_signing_key_failed_on_1st_time, - signing_key_interface_factory: mocked_signing_key_interface_factory_valid + fetch_signing_key: mocked_fetch_signing_key_failed_on_1st_time, + create_signing_key_provider: mocked_create_signing_key_provider_valid ).call( authentication_parameters: authentication_parameters_with_valid_token ) @@ -393,9 +393,9 @@ def valid_decoded_token(claims) context "and failed to fetch keys from provider" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( - fetch_signing_key_from_cache: mocked_fetch_signing_key_failed_on_2nd_time, + fetch_signing_key: mocked_fetch_signing_key_failed_on_2nd_time, verify_and_decode_token: mocked_verify_and_decode_token_invalid, - signing_key_interface_factory: mocked_signing_key_interface_factory_valid + create_signing_key_provider: mocked_create_signing_key_provider_valid ).call( authentication_parameters: authentication_parameters_with_valid_token ) @@ -409,9 +409,9 @@ def valid_decoded_token(claims) context "and succeed to fetch keys from provider" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( - fetch_signing_key_from_cache: mocked_fetch_signing_key_always_succeed, + fetch_signing_key: mocked_fetch_signing_key_always_succeed, verify_and_decode_token: mocked_verify_and_decode_token_invalid, - signing_key_interface_factory: mocked_signing_key_interface_factory_valid + create_signing_key_provider: mocked_create_signing_key_provider_valid ).call( authentication_parameters: authentication_parameters_with_valid_token ) @@ -427,11 +427,11 @@ def valid_decoded_token(claims) context "and keys are not updated" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( - fetch_signing_key_from_cache: mocked_fetch_signing_key_always_succeed, + fetch_signing_key: mocked_fetch_signing_key_always_succeed, verify_and_decode_token: mocked_verify_and_decode_token_succeed_on_2nd_time, fetch_jwt_claims_to_validate: mocked_fetch_jwt_claims_to_validate_valid, get_verification_option_by_jwt_claim: mocked_get_verification_option_by_jwt_claim_valid, - signing_key_interface_factory: mocked_signing_key_interface_factory_valid + create_signing_key_provider: mocked_create_signing_key_provider_valid ).call( authentication_parameters: authentication_parameters_with_valid_token ) @@ -445,11 +445,11 @@ def valid_decoded_token(claims) context "and keys are updated" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( - fetch_signing_key_from_cache: mocked_fetch_signing_key_always_succeed, + fetch_signing_key: mocked_fetch_signing_key_always_succeed, verify_and_decode_token: mocked_verify_and_decode_token_succeed_on_1st_time, fetch_jwt_claims_to_validate: mocked_fetch_jwt_claims_to_validate_valid, get_verification_option_by_jwt_claim: mocked_get_verification_option_by_jwt_claim_valid, - signing_key_interface_factory: mocked_signing_key_interface_factory_valid + create_signing_key_provider: mocked_create_signing_key_provider_valid ).call( authentication_parameters: authentication_parameters_with_valid_token ) @@ -467,10 +467,10 @@ def valid_decoded_token(claims) context "and failed to fetch enforced claims" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( - fetch_signing_key_from_cache: mocked_fetch_signing_key_always_succeed, + fetch_signing_key: mocked_fetch_signing_key_always_succeed, verify_and_decode_token: mocked_verify_and_decode_token_succeed_on_1st_time, fetch_jwt_claims_to_validate: mocked_fetch_jwt_claims_to_validate_invalid, - signing_key_interface_factory: mocked_signing_key_interface_factory_valid + create_signing_key_provider: mocked_create_signing_key_provider_valid ).call( authentication_parameters: authentication_parameters_with_valid_token ) @@ -485,10 +485,10 @@ def valid_decoded_token(claims) context "with empty claims list to validate" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( - fetch_signing_key_from_cache: mocked_fetch_signing_key_always_succeed, + fetch_signing_key: mocked_fetch_signing_key_always_succeed, verify_and_decode_token: mocked_verify_and_decode_token_succeed_on_1st_time, fetch_jwt_claims_to_validate: mocked_fetch_jwt_claims_to_validate_with_empty_claims, - signing_key_interface_factory: mocked_signing_key_interface_factory_valid + create_signing_key_provider: mocked_create_signing_key_provider_valid ).call( authentication_parameters: authentication_parameters_with_valid_token ) @@ -502,10 +502,10 @@ def valid_decoded_token(claims) context "with mandatory claims which do not exist in token" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( - fetch_signing_key_from_cache: mocked_fetch_signing_key_always_succeed, + fetch_signing_key: mocked_fetch_signing_key_always_succeed, verify_and_decode_token: mocked_verify_and_decode_token_succeed_on_1st_time, fetch_jwt_claims_to_validate: mocked_fetch_jwt_claims_to_validate_with_not_exist_claims_in_token, - signing_key_interface_factory: mocked_signing_key_interface_factory_valid + create_signing_key_provider: mocked_create_signing_key_provider_valid ).call( authentication_parameters: authentication_parameters_with_valid_token ) @@ -519,11 +519,11 @@ def valid_decoded_token(claims) context "and failed to get verification options" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( - fetch_signing_key_from_cache: mocked_fetch_signing_key_always_succeed, + fetch_signing_key: mocked_fetch_signing_key_always_succeed, verify_and_decode_token: mocked_verify_and_decode_token_succeed_on_1st_time, fetch_jwt_claims_to_validate: mocked_fetch_jwt_claims_to_validate_valid, get_verification_option_by_jwt_claim: mocked_get_verification_option_by_jwt_claim_invalid, - signing_key_interface_factory: mocked_signing_key_interface_factory_valid + create_signing_key_provider: mocked_create_signing_key_provider_valid ).call( authentication_parameters: authentication_parameters_with_valid_token ) @@ -544,11 +544,11 @@ def valid_decoded_token(claims) context "and failed to validate claims" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( - fetch_signing_key_from_cache: mocked_fetch_signing_key_always_succeed, + fetch_signing_key: mocked_fetch_signing_key_always_succeed, verify_and_decode_token: mocked_verify_and_decode_token_failed_to_validate_claims, fetch_jwt_claims_to_validate: mocked_fetch_jwt_claims_to_validate_valid, get_verification_option_by_jwt_claim: mocked_get_verification_option_by_jwt_claim_valid, - signing_key_interface_factory: mocked_signing_key_interface_factory_valid + create_signing_key_provider: mocked_create_signing_key_provider_valid ).call( authentication_parameters: authentication_parameters_with_valid_token ) @@ -563,11 +563,11 @@ def valid_decoded_token(claims) context "and keys are not updated" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( - fetch_signing_key_from_cache: mocked_fetch_signing_key_always_succeed, + fetch_signing_key: mocked_fetch_signing_key_always_succeed, verify_and_decode_token: mocked_verify_and_decode_token_succeed_to_validate_claims_when_keys_not_updated, fetch_jwt_claims_to_validate: mocked_fetch_jwt_claims_to_validate_valid, get_verification_option_by_jwt_claim: mocked_get_verification_option_by_jwt_claim_valid, - signing_key_interface_factory: mocked_signing_key_interface_factory_valid + create_signing_key_provider: mocked_create_signing_key_provider_valid ).call( authentication_parameters: authentication_parameters_with_valid_token ) @@ -581,11 +581,11 @@ def valid_decoded_token(claims) context "and keys are updated" do subject do ::Authentication::AuthnJwt::ValidateAndDecode::ValidateAndDecodeToken.new( - fetch_signing_key_from_cache: mocked_fetch_signing_key_always_succeed, + fetch_signing_key: mocked_fetch_signing_key_always_succeed, verify_and_decode_token: mocked_verify_and_decode_token_succeed_to_validate_claims_when_keys_updated, fetch_jwt_claims_to_validate: mocked_fetch_jwt_claims_to_validate_valid, get_verification_option_by_jwt_claim: mocked_get_verification_option_by_jwt_claim_valid, - signing_key_interface_factory: mocked_signing_key_interface_factory_valid + create_signing_key_provider: mocked_create_signing_key_provider_valid ).call( authentication_parameters: authentication_parameters_with_valid_token ) diff --git a/spec/app/domain/authentication/authn-jwt/validate_status_spec.rb b/spec/app/domain/authentication/authn-jwt/validate_status_spec.rb index 25e6fa434c..12f701855e 100644 --- a/spec/app/domain/authentication/authn-jwt/validate_status_spec.rb +++ b/spec/app/domain/authentication/authn-jwt/validate_status_spec.rb @@ -23,8 +23,8 @@ } let(:mocked_logger) { double("Mocked logger") } - let(:mocked_valid_create_signing_key_interface) { double("Mocked valid create signing key interface") } - let(:mocked_invalid_create_signing_key_interface) { double("Mocked invalid create signing key interface") } + let(:mocked_valid_create_signing_key_provider) { double("Mocked valid create signing key interface") } + let(:mocked_invalid_create_signing_key_provider) { double("Mocked invalid create signing key interface") } let(:mocked_valid_fetch_issuer_value) { double("Mocked valid fetch issuer value") } let(:mocked_invalid_fetch_issuer_value) { double("Mocked invalid fetch issuer value") } let(:mocked_invalid_fetch_audience_value) { double("Mocked invalid audience issuer value") } @@ -54,24 +54,24 @@ let(:user_cant_access_webservice_error) { "User cant access webservice" } let(:webservice_does_not_exist_error) { "Webservice does not exist" } let(:account_does_not_exist_error) { "Account does not exist" } - let(:mocked_valid_signing_key_interface) { double("Mocked valid signing key interface") } - let(:mocked_valid_fetch_signing_key_from_cache) { double("Mocked valid fetch signing key interface") } + let(:mocked_valid_signing_key_provider) { double("Mocked valid signing key interface") } + let(:mocked_valid_fetch_signing_key) { double("Mocked valid fetch signing key interface") } before(:each) do - allow(mocked_valid_create_signing_key_interface).to( - receive(:call).and_return(mocked_valid_signing_key_interface) + allow(mocked_valid_create_signing_key_provider).to( + receive(:call).and_return(mocked_valid_signing_key_provider) ) - allow(mocked_valid_signing_key_interface).to( + allow(mocked_valid_signing_key_provider).to( receive(:signing_key_uri).and_return(valid_signing_key_uri) ) - allow(mocked_valid_fetch_signing_key_from_cache).to( + allow(mocked_valid_fetch_signing_key).to( receive(:call).and_return(valid_signing_key) ) - allow(mocked_invalid_create_signing_key_interface).to( + allow(mocked_invalid_create_signing_key_provider).to( receive(:call).and_raise(create_signing_key_configuration_is_invalid_error) ) @@ -166,8 +166,8 @@ subject do ::Authentication::AuthnJwt::ValidateStatus.new( - fetch_signing_key_from_cache: mocked_valid_fetch_signing_key_from_cache, - create_signing_key_interface: mocked_valid_create_signing_key_interface, + fetch_signing_key: mocked_valid_fetch_signing_key, + create_signing_key_provider: mocked_valid_create_signing_key_provider, fetch_issuer_value: mocked_valid_fetch_issuer_value, identity_from_decoded_token_provider_class: mocked_valid_identity_from_decoded_token_provider, validate_webservice_is_whitelisted: mocked_valid_validate_webservice_is_whitelisted, @@ -191,8 +191,8 @@ subject do ::Authentication::AuthnJwt::ValidateStatus.new( - fetch_signing_key_from_cache: mocked_valid_fetch_signing_key_from_cache, - create_signing_key_interface: mocked_valid_create_signing_key_interface, + fetch_signing_key: mocked_valid_fetch_signing_key, + create_signing_key_provider: mocked_valid_create_signing_key_provider, fetch_issuer_value: mocked_valid_fetch_issuer_value, identity_from_decoded_token_provider_class: mocked_valid_identity_from_decoded_token_provider, validate_webservice_is_whitelisted: mocked_valid_validate_webservice_is_whitelisted, @@ -215,8 +215,8 @@ subject do ::Authentication::AuthnJwt::ValidateStatus.new( - fetch_signing_key_from_cache: mocked_valid_fetch_signing_key_from_cache, - create_signing_key_interface: mocked_valid_create_signing_key_interface, + fetch_signing_key: mocked_valid_fetch_signing_key, + create_signing_key_provider: mocked_valid_create_signing_key_provider, fetch_issuer_value: mocked_valid_fetch_issuer_value, identity_from_decoded_token_provider_class: mocked_valid_identity_from_decoded_token_provider, validate_webservice_is_whitelisted: mocked_valid_validate_webservice_is_whitelisted, @@ -239,8 +239,8 @@ subject do ::Authentication::AuthnJwt::ValidateStatus.new( - fetch_signing_key_from_cache: mocked_valid_fetch_signing_key_from_cache, - create_signing_key_interface: mocked_valid_create_signing_key_interface, + fetch_signing_key: mocked_valid_fetch_signing_key, + create_signing_key_provider: mocked_valid_create_signing_key_provider, fetch_issuer_value: mocked_valid_fetch_issuer_value, identity_from_decoded_token_provider_class: mocked_valid_identity_from_decoded_token_provider, validate_webservice_is_whitelisted: mocked_valid_validate_webservice_is_whitelisted, @@ -263,8 +263,8 @@ subject do ::Authentication::AuthnJwt::ValidateStatus.new( - fetch_signing_key_from_cache: mocked_valid_fetch_signing_key_from_cache, - create_signing_key_interface: mocked_valid_create_signing_key_interface, + fetch_signing_key: mocked_valid_fetch_signing_key, + create_signing_key_provider: mocked_valid_create_signing_key_provider, fetch_issuer_value: mocked_valid_fetch_issuer_value, identity_from_decoded_token_provider_class: mocked_valid_identity_from_decoded_token_provider, validate_webservice_is_whitelisted: mocked_invalid_validate_webservice_is_whitelisted, @@ -299,8 +299,8 @@ subject do ::Authentication::AuthnJwt::ValidateStatus.new( - fetch_signing_key_from_cache: mocked_valid_fetch_signing_key_from_cache, - create_signing_key_interface: mocked_valid_create_signing_key_interface, + fetch_signing_key: mocked_valid_fetch_signing_key, + create_signing_key_provider: mocked_valid_create_signing_key_provider, fetch_issuer_value: mocked_valid_fetch_issuer_value, identity_from_decoded_token_provider_class: mocked_valid_identity_from_decoded_token_provider, validate_webservice_is_whitelisted: mocked_valid_validate_webservice_is_whitelisted, @@ -324,8 +324,8 @@ context "signing key secrets are not configured properly" do subject do ::Authentication::AuthnJwt::ValidateStatus.new( - fetch_signing_key_from_cache: mocked_valid_fetch_signing_key_from_cache, - create_signing_key_interface: mocked_invalid_create_signing_key_interface, + fetch_signing_key: mocked_valid_fetch_signing_key, + create_signing_key_provider: mocked_invalid_create_signing_key_provider, fetch_issuer_value: mocked_valid_fetch_issuer_value, identity_from_decoded_token_provider_class: mocked_valid_identity_from_decoded_token_provider, validate_webservice_is_whitelisted: mocked_valid_validate_webservice_is_whitelisted, @@ -347,8 +347,8 @@ context "issuer secrets are not configured properly" do subject do ::Authentication::AuthnJwt::ValidateStatus.new( - fetch_signing_key_from_cache: mocked_valid_fetch_signing_key_from_cache, - create_signing_key_interface: mocked_valid_create_signing_key_interface, + fetch_signing_key: mocked_valid_fetch_signing_key, + create_signing_key_provider: mocked_valid_create_signing_key_provider, fetch_issuer_value: mocked_invalid_fetch_issuer_value, identity_from_decoded_token_provider_class: mocked_valid_identity_from_decoded_token_provider, validate_webservice_is_whitelisted: mocked_valid_validate_webservice_is_whitelisted, @@ -370,8 +370,8 @@ context "audience secret is not configured properly" do subject do ::Authentication::AuthnJwt::ValidateStatus.new( - fetch_signing_key_from_cache: mocked_valid_fetch_signing_key_from_cache, - create_signing_key_interface: mocked_valid_create_signing_key_interface, + fetch_signing_key: mocked_valid_fetch_signing_key, + create_signing_key_provider: mocked_valid_create_signing_key_provider, fetch_issuer_value: mocked_valid_fetch_issuer_value, fetch_audience_value: mocked_invalid_fetch_audience_value, identity_from_decoded_token_provider_class: mocked_valid_identity_from_decoded_token_provider, @@ -394,8 +394,8 @@ context "enforced claims is not configured properly" do subject do ::Authentication::AuthnJwt::ValidateStatus.new( - fetch_signing_key_from_cache: mocked_valid_fetch_signing_key_from_cache, - create_signing_key_interface: mocked_valid_create_signing_key_interface, + fetch_signing_key: mocked_valid_fetch_signing_key, + create_signing_key_provider: mocked_valid_create_signing_key_provider, fetch_issuer_value: mocked_valid_fetch_issuer_value, fetch_enforced_claims: mocked_invalid_fetch_enforced_claims, identity_from_decoded_token_provider_class: mocked_valid_identity_from_decoded_token_provider, @@ -418,8 +418,8 @@ context "mapping claims is not configured properly" do subject do ::Authentication::AuthnJwt::ValidateStatus.new( - fetch_signing_key_from_cache: mocked_valid_fetch_signing_key_from_cache, - create_signing_key_interface: mocked_valid_create_signing_key_interface, + fetch_signing_key: mocked_valid_fetch_signing_key, + create_signing_key_provider: mocked_valid_create_signing_key_provider, fetch_issuer_value: mocked_valid_fetch_issuer_value, fetch_mapping_claims: mocked_invalid_fetch_mapping_claims, identity_from_decoded_token_provider_class: mocked_valid_identity_from_decoded_token_provider, @@ -442,8 +442,8 @@ context "identity secrets are not configured properly" do subject do ::Authentication::AuthnJwt::ValidateStatus.new( - fetch_signing_key_from_cache: mocked_valid_fetch_signing_key_from_cache, - create_signing_key_interface: mocked_valid_create_signing_key_interface, + fetch_signing_key: mocked_valid_fetch_signing_key, + create_signing_key_provider: mocked_valid_create_signing_key_provider, fetch_issuer_value: mocked_valid_fetch_issuer_value, identity_from_decoded_token_provider_class: mocked_invalid_identity_from_decoded_token_provider, validate_webservice_is_whitelisted: mocked_valid_validate_webservice_is_whitelisted,