Skip to content

Commit

Permalink
Wrap jwks calls
Browse files Browse the repository at this point in the history
  • Loading branch information
gl-johnson committed Sep 1, 2023
1 parent dffad96 commit 38701a4
Show file tree
Hide file tree
Showing 17 changed files with 104 additions and 12 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
[cyberark/conjur#2901](https://github.com/cyberark/conjur/pull/2901)

### Added
- Support an optional`ca-cert` variable for providing custom certs/chains for to verify
OIDC providers or proxies when using the OIDC authenticator
[cyberark/conjur#2933](https://github.com/cyberark/conjur/pull/2933)
- New flag to `conjurctl server` command called `--no-migrate` which allows for skipping
the database migration step when starting the server.
[cyberark/conjur#2895](https://github.com/cyberark/conjur/pull/2895)
Expand Down
13 changes: 10 additions & 3 deletions app/domain/authentication/authn_oidc/v2/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,9 @@ def discovery_information(invalidate: false)
force: invalidate,
skip_nil: true
) do
self.discover(
self.class.discover(
provider_uri: @authenticator.provider_uri,
discovery_configuration: @discovery_configuration,
cert_string: @authenticator.ca_cert
)
rescue Errno::ETIMEDOUT => e
Expand All @@ -186,9 +187,15 @@ def self.discover(
provider_uri:,
discovery_configuration: ::OpenIDConnect::Discovery::Provider::Config,
cert_dir: OpenSSL::X509::DEFAULT_CERT_DIR,
cert_string: nil
cert_string: nil,
jwks: false
)
d = -> { discovery_configuration.discover!(provider_uri) }
case jwks
when false
d = -> { discovery_configuration.discover!(provider_uri) }
when true
d = -> { discovery_configuration.discover!(provider_uri).jwks }
end

return d.call if cert_string.blank?

Expand Down
2 changes: 1 addition & 1 deletion app/domain/authentication/authn_oidc/v2/strategy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def callback(args)
code: args[:code],
nonce: args[:nonce],
code_verifier: args[:code_verifier],
ca_cert: @authenticator.ca_cert
cert_string: @authenticator.ca_cert
)
)
unless identity.present?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def log_provider_uri
def discover_provider
@discovered_provider = Authentication::AuthnOidc::V2::Client.discover(
provider_uri: @provider_uri,
discovery_configuration: @open_id_discovery_service,
cert_string: @ca_cert
)
@logger.debug(
Expand Down
8 changes: 7 additions & 1 deletion app/domain/authentication/o_auth/fetch_provider_keys.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,14 @@ def discovered_provider
end

def fetch_provider_keys
# We have to invoke the custom discovery service to be able to fetch the jwks
# since it also requires the CA to invoke the jwks URI
jwks = {
keys: @discovered_provider.jwks
keys: Authentication::AuthnOidc::V2::Client.discover(
provider_uri: @provider_uri,
cert_string: @ca_cert,
jwks: true
)
}
algs = @discovered_provider.id_token_signing_alg_values_supported
@logger.debug(LogMessages::Authentication::OAuth::FetchProviderKeysSuccess.new)
Expand Down
5 changes: 2 additions & 3 deletions ci/oauth/keycloak/fetch_certificate
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,5 @@ openssl s_client \
-outform PEM \
>/etc/ssl/certs/keycloak.pem

# Skip this step so we can test the 'ca-cert' variable configuration
# hash=$(openssl x509 -hash -in /etc/ssl/certs/keycloak.pem -out /dev/null)
# ln -s /etc/ssl/certs/keycloak.pem "/etc/ssl/certs/${hash}.0" || true
hash=$(openssl x509 -hash -in /etc/ssl/certs/keycloak.pem -out /dev/null)
ln -s /etc/ssl/certs/keycloak.pem "/etc/ssl/certs/${hash}.0" || true
4 changes: 3 additions & 1 deletion ci/shared.sh
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,13 @@ _run_cucumber_tests() {
cucumber -ec "\
/oauth/keycloak/scripts/fetch_certificate &&
bundle exec parallel_cucumber . -n ${PARALLEL_PROCESSES} \
-o '--strict --profile \"${profile}\" ${cucumber_tags_arg} \
-o '--strict --backtrace --profile \"${profile}\" ${cucumber_tags_arg} \
--format json --out \"cucumber/$profile/cucumber_results.json\" \
--format html --out \"cucumber/$profile/cucumber_results.html\" \
--format junit --out \"cucumber/$profile/features/reports\"'"

$COMPOSE logs

# Stage 4: Coverage results
# -----------------------------------------------------------

Expand Down
11 changes: 10 additions & 1 deletion ci/test_suites/authenticators_oidc/test
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
set -e
set -ex

# This file has an implicit dependency on the environment variables defined in
# "ci/docker-compose.yml" keycloak section.
Expand All @@ -23,6 +23,7 @@ function _hydrate_all_env_args() {
# shellcheck disable=SC2034
arr=(
"${keycloak_items[@]}"
"KEYCLOAK_CA_CERT=$($COMPOSE exec conjur cat /etc/ssl/certs/keycloak.pem)"
"PROVIDER_URI=https://keycloak:8443/auth/realms/master"
"PROVIDER_INTERNAL_URI=http://keycloak:8080/auth/realms/master/protocol/openid-connect"
"PROVIDER_ISSUER=http://keycloak:8080/auth/realms/master"
Expand All @@ -49,6 +50,14 @@ function main() {
create_keycloak_users
fetch_keycloak_certificate

# Delete the symlink so we can test with the 'ca-cert' variable
local conjur_parallel_services
read -ra conjur_parallel_services <<< "$(get_parallel_services 'conjur')"
for parallel_service in "${conjur_parallel_services[@]}"; do
hash=$($COMPOSE exec "${parallel_service}" openssl x509 -hash -in /etc/ssl/certs/keycloak.pem -out /dev/null)
$COMPOSE exec "${parallel_service}" rm "/etc/ssl/certs/$hash.0" || true
done

additional_services='ldap-server keycloak'
_run_cucumber_tests authenticators_oidc "$additional_services" \
_hydrate_all_env_args
Expand Down
5 changes: 5 additions & 0 deletions cucumber/authenticators_oidc/features/authn_oidc.feature
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Feature: OIDC Authenticator - Hosts can authenticate with OIDC authenticator
| oidc_client_secret | KEYCLOAK_CLIENT_SECRET | 1234 |
| oidc_provider_uri | PROVIDER_URI | https://keycloak:8443/auth/realms/master |
| oidc_id_token_user_property | ID_TOKEN_USER_PROPERTY | preferred_username |
| oidc_ca_cert | KEYCLOAK_CA_CERT | |

And I load a policy:
"""
Expand All @@ -31,6 +32,9 @@ Feature: OIDC Authenticator - Hosts can authenticate with OIDC authenticator
- !variable
id: id-token-user-property
- !variable
id: ca-cert
- !group users
- !permit
Expand All @@ -48,6 +52,7 @@ Feature: OIDC Authenticator - Hosts can authenticate with OIDC authenticator
| variable_id | context_variable |
| conjur/authn-oidc/keycloak/id-token-user-property | oidc_id_token_user_property |
| conjur/authn-oidc/keycloak/provider-uri | oidc_provider_uri |
| conjur/authn-oidc/keycloak/ca-cert | oidc_ca_cert |

@smoke
Scenario: A valid id token in header to get Conjur access token
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Feature: OIDC Authenticator - Bad authenticator configuration leads to an error
| oidc_client_secret | KEYCLOAK_CLIENT_SECRET | 1234 |
| oidc_provider_uri | PROVIDER_URI | https://keycloak:8443/auth/realms/master |
| oidc_id_token_user_property | ID_TOKEN_USER_PROPERTY | preferred_username |
| oidc_ca_cert | KEYCLOAK_CA_CERT | |

@negative @acceptance
Scenario: id-token-user-property variable missing in policy is denied
Expand All @@ -29,6 +30,9 @@ Feature: OIDC Authenticator - Bad authenticator configuration leads to an error
- !variable
id: provider-uri
- !variable
id: ca-cert
- !group users
Expand All @@ -46,6 +50,7 @@ Feature: OIDC Authenticator - Bad authenticator configuration leads to an error
And I set the following conjur variables:
| variable_id | context_variable |
| conjur/authn-oidc/keycloak/provider-uri | oidc_provider_uri |
| conjur/authn-oidc/keycloak/ca-cert | oidc_ca_cert |
And I fetch an ID Token for username "alice" and password "alice"
And I save my place in the log file
When I authenticate via OIDC with id token
Expand Down Expand Up @@ -108,6 +113,9 @@ Feature: OIDC Authenticator - Bad authenticator configuration leads to an error
- !variable
id: id-token-user-property
- !variable
id: ca-cert
- !group users
- !user alice
Expand All @@ -120,6 +128,7 @@ Feature: OIDC Authenticator - Bad authenticator configuration leads to an error
| variable_id | context_variable |
| conjur/authn-oidc/keycloak/id-token-user-property | oidc_id_token_user_property |
| conjur/authn-oidc/keycloak/provider-uri | oidc_provider_uri |
| conjur/authn-oidc/keycloak/ca-cert | oidc_ca_cert |
And I fetch an ID Token for username "alice" and password "alice"
And I save my place in the log file
When I authenticate via OIDC with id token
Expand All @@ -146,6 +155,9 @@ Feature: OIDC Authenticator - Bad authenticator configuration leads to an error
- !variable
id: id-token-user-property
- !variable
id: ca-cert
- !group users
- !permit
Expand All @@ -163,6 +175,7 @@ Feature: OIDC Authenticator - Bad authenticator configuration leads to an error
| variable_id | context_variable |
| conjur/authn-oidc/keycloak/id-token-user-property | oidc_id_token_user_property |
| conjur/authn-oidc/keycloak/provider-uri | oidc_provider_uri |
| conjur/authn-oidc/keycloak/ca-cert | oidc_ca_cert |
And I fetch an ID Token for username "alice" and password "alice"
And I save my place in the log file
When I authenticate via OIDC with id token
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Feature: OIDC Authenticator - Performance tests
| oidc_client_secret | KEYCLOAK_CLIENT_SECRET | 1234 |
| oidc_provider_uri | PROVIDER_URI | https://keycloak:8443/auth/realms/master |
| oidc_id_token_user_property | ID_TOKEN_USER_PROPERTY | preferred_username |
| oidc_ca_cert | KEYCLOAK_CA_CERT | |

And I load a policy:
"""
Expand All @@ -31,6 +32,9 @@ Feature: OIDC Authenticator - Performance tests
- !variable
id: id-token-user-property
- !variable
id: ca-cert
- !group users
- !permit
Expand All @@ -48,6 +52,7 @@ Feature: OIDC Authenticator - Performance tests
| variable_id | context_variable |
| conjur/authn-oidc/keycloak/id-token-user-property | oidc_id_token_user_property |
| conjur/authn-oidc/keycloak/provider-uri | oidc_provider_uri |
| conjur/authn-oidc/keycloak/ca-cert | oidc_ca_cert |

@performance
Scenario: successful requests
Expand Down
5 changes: 5 additions & 0 deletions cucumber/authenticators_oidc/features/authn_oidc_v2.feature
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Feature: OIDC Authenticator V2 - Users can authenticate with OIDC authenticator
| oidc_provider_uri | PROVIDER_URI | https://keycloak:8443/auth/realms/master |
| oidc_claim_mapping | ID_TOKEN_USER_PROPERTY | preferred_username |
| oidc_redirect_url | KEYCLOAK_REDIRECT_URI | http://conjur:3000/authn-oidc/keycloak2/cucumber/authenticate |
| oidc_ca_cert | KEYCLOAK_CA_CERT | |

And I load a policy:
"""
Expand All @@ -36,6 +37,7 @@ Feature: OIDC Authenticator V2 - Users can authenticate with OIDC authenticator
- !variable redirect-uri
- !variable provider-scope
- !variable token-ttl
- !variable ca-cert
- !group users
- !permit
role: !group users
Expand All @@ -59,6 +61,7 @@ Feature: OIDC Authenticator V2 - Users can authenticate with OIDC authenticator
- !variable redirect-uri
- !variable provider-scope
- !variable token-ttl
- !variable ca-cert
- !group users
- !permit
role: !group users
Expand All @@ -83,13 +86,15 @@ Feature: OIDC Authenticator V2 - Users can authenticate with OIDC authenticator
| conjur/authn-oidc/keycloak2/claim-mapping | oidc_claim_mapping | |
| conjur/authn-oidc/keycloak2/redirect-uri | oidc_redirect_url | |
| conjur/authn-oidc/keycloak2/response-type | | code |
| conjur/authn-oidc/keycloak2/ca-cert | oidc_ca_cert | |
| conjur/authn-oidc/keycloak2-long-lived/provider-uri | oidc_provider_uri | |
| conjur/authn-oidc/keycloak2-long-lived/client-id | oidc_client_id | |
| conjur/authn-oidc/keycloak2-long-lived/client-secret | oidc_client_secret | |
| conjur/authn-oidc/keycloak2-long-lived/claim-mapping | oidc_claim_mapping | |
| conjur/authn-oidc/keycloak2-long-lived/redirect-uri | oidc_redirect_url | |
| conjur/authn-oidc/keycloak2-long-lived/response-type | | code |
| conjur/authn-oidc/keycloak2-long-lived/token-ttl | | PT2H |
| conjur/authn-oidc/keycloak2-long-lived/ca-cert | oidc_ca_cert | |

@smoke
Scenario: A valid code to get Conjur access token from webservice with default token TTL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Feature: OIDC Authenticator - Users can authenticate with OIDC & LDAP authentica
| oidc_client_secret | KEYCLOAK_CLIENT_SECRET | 1234 |
| oidc_provider_uri | PROVIDER_URI | https://keycloak:8443/auth/realms/master |
| oidc_id_token_user_property | ID_TOKEN_USER_PROPERTY | preferred_username |
| oidc_ca_cert | KEYCLOAK_CA_CERT | |

# Configure OIDC authenticator
And I load a policy:
Expand All @@ -28,6 +29,8 @@ Feature: OIDC Authenticator - Users can authenticate with OIDC & LDAP authentica
id: provider-uri
- !variable
id: id-token-user-property
- !variable
id: ca-cert
- !group users
- !permit
role: !group users
Expand All @@ -42,6 +45,7 @@ Feature: OIDC Authenticator - Users can authenticate with OIDC & LDAP authentica
| variable_id | context_variable |
| conjur/authn-oidc/keycloak/id-token-user-property | oidc_id_token_user_property |
| conjur/authn-oidc/keycloak/provider-uri | oidc_provider_uri |
| conjur/authn-oidc/keycloak/ca-cert | oidc_ca_cert |

# Configure LDAP authenticator
And I extend the policy with:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Feature: OIDC Authenticator - Status Check
| context_variable | environment_variable | default_value |
| oidc_provider_uri | PROVIDER_URI | https://keycloak:8443/auth/realms/master |
| oidc_claim_mapping | ID_TOKEN_USER_PROPERTY | preferred_username |
| oidc_ca_cert | KEYCLOAK_CA_CERT | |

@smoke
Scenario: A properly configured OIDC authenticator returns a successful response
Expand All @@ -28,6 +29,9 @@ Feature: OIDC Authenticator - Status Check
- !variable
id: id-token-user-property
- !variable
id: ca-cert
- !group users
Expand Down Expand Up @@ -60,7 +64,7 @@ Feature: OIDC Authenticator - Status Check
| variable_id | context_variable | default_value |
| conjur/authn-oidc/keycloak/provider-uri | oidc_provider_uri | |
| conjur/authn-oidc/keycloak/id-token-user-property | oidc_claim_mapping | |

| conjur/authn-oidc/keycloak/ca-cert | oidc_ca_cert | |
And I login as "alice"
When I GET "/authn-oidc/keycloak/cucumber/status"
Then the HTTP response status code is 200
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@
http.use_ssl = true
# Don't verify (to simplify self-signed certificate)
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

# if service_id.include?('keycloak') && ENV['KEYCLOAK_CA_CERT']
# http.cert_store = OpenSSL::X509::Store.new
# http.cert_store.set_default_paths
# http.cert_store.add_cert(OpenSSL::X509::Certificate.new(ENV['KEYCLOAK_CA_CERT']))
# end

request = Net::HTTP::Get.new("#{redirect_uri.path}?#{redirect_uri.query}")
response = http.request(request)

Expand All @@ -59,6 +66,13 @@
http = Net::HTTP.new(post_uri.host, post_uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

# if service_id.include?('keycloak') && ENV['KEYCLOAK_CA_CERT']
# http.cert_store = OpenSSL::X509::Store.new
# http.cert_store.set_default_paths
# http.cert_store.add_cert(OpenSSL::X509::Certificate.new(ENV['KEYCLOAK_CA_CERT']))
# end

request = Net::HTTP::Post.new(post_uri.request_uri)
request['Cookie'] = cookies_arrays.join('; ')
request.set_form_data({ 'username' => username, 'password' => password })
Expand Down
5 changes: 4 additions & 1 deletion dev/start
Original file line number Diff line number Diff line change
Expand Up @@ -318,9 +318,12 @@ configure_oidc_v2() {
client_add_secret "conjur/authn-oidc/$service_id/client-id" "$client_id"
client_add_secret "conjur/authn-oidc/$service_id/client-secret" "$client_secret"
client_add_secret "conjur/authn-oidc/$service_id/claim-mapping" "$claim_mapping"
client_add_secret "conjur/authn-oidc/$service_id/redirect_uri" "http://localhost:3000/authn-oidc/$service_id/cucumber/authenticate"
client_add_secret "conjur/authn-oidc/$service_id/redirect_uri" "http://127.0.0.1:8000/callback"
if [ "$service_id" = "keycloak2" ]; then
client_add_secret "conjur/authn-oidc/$service_id/ca-cert" "$($COMPOSE exec conjur cat /etc/ssl/certs/keycloak.pem)"
# Delete the symlink so we can test with the 'ca-cert' variable
hash=$($COMPOSE exec conjur openssl x509 -hash -in /etc/ssl/certs/keycloak.pem -out /dev/null)
$COMPOSE exec conjur rm "/etc/ssl/certs/$hash.0" || true
fi

client_load_policy "/src/conjur-server/dev/policies/authenticators/authn-oidc/$service_id-users.yml"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@ def mock_discovery_provider(error:)
end
end

# def mock_oidc_client(error:)
# double('oidc_client').tap do |oidc_client|
# if error
# allow (oidc_client).to receive(:discover)
# .and_raise(error)
# else
# allow (oidc_client).to receive(:discover)
# .and_return(mock_provider)
# end
# end
# end

context "A discoverable identity provider" do
subject do
Authentication::OAuth::DiscoverIdentityProvider.new(
Expand Down

0 comments on commit 38701a4

Please sign in to comment.