Minor refactor
Improve logging Fix an issue running selenium tests locally WIP modify schema to configure queryParameters for oauth2 endpoints
This commit is contained in:
parent
7aca1605eb
commit
4da45996ca
|
@ -254,7 +254,7 @@ get_oauth_provider(ListOfRequiredAttributes) ->
|
||||||
|
|
||||||
get_oauth_provider_from_keyconfig(ListOfRequiredAttributes) ->
|
get_oauth_provider_from_keyconfig(ListOfRequiredAttributes) ->
|
||||||
OAuthProvider = lookup_oauth_provider_from_keyconfig(),
|
OAuthProvider = lookup_oauth_provider_from_keyconfig(),
|
||||||
rabbit_log:debug("Using oauth_provider ~s from keyconfig", [format_oauth_provider(OAuthProvider)]),
|
rabbit_log:debug("Using oauth_provider ~p from keyconfig", [format_oauth_provider(OAuthProvider)]),
|
||||||
case find_missing_attributes(OAuthProvider, ListOfRequiredAttributes) of
|
case find_missing_attributes(OAuthProvider, ListOfRequiredAttributes) of
|
||||||
[] ->
|
[] ->
|
||||||
{ok, OAuthProvider};
|
{ok, OAuthProvider};
|
||||||
|
@ -557,27 +557,27 @@ format_ssl_options(TlsOptions) ->
|
||||||
[] -> 0;
|
[] -> 0;
|
||||||
Certs -> length(Certs)
|
Certs -> length(Certs)
|
||||||
end,
|
end,
|
||||||
io_lib:format("{verify: ~p, fail_if_no_peer_cert: ~p, crl_check: ~p, " ++
|
lists:flatten(io_lib:format("{verify: ~p, fail_if_no_peer_cert: ~p, crl_check: ~p, " ++
|
||||||
"depth: ~p, cacertfile: ~p, cacerts(count): ~p }", [
|
"depth: ~p, cacertfile: ~p, cacerts(count): ~p }", [
|
||||||
proplists:get_value(verify, TlsOptions),
|
proplists:get_value(verify, TlsOptions),
|
||||||
proplists:get_value(fail_if_no_peer_cert, TlsOptions),
|
proplists:get_value(fail_if_no_peer_cert, TlsOptions),
|
||||||
proplists:get_value(crl_check, TlsOptions),
|
proplists:get_value(crl_check, TlsOptions),
|
||||||
proplists:get_value(depth, TlsOptions),
|
proplists:get_value(depth, TlsOptions),
|
||||||
proplists:get_value(cacertfile, TlsOptions),
|
proplists:get_value(cacertfile, TlsOptions),
|
||||||
CaCertsCount]).
|
CaCertsCount])).
|
||||||
|
|
||||||
format_oauth_provider_id(root) -> "<from keyconfig>";
|
format_oauth_provider_id(root) -> "<from keyconfig>";
|
||||||
format_oauth_provider_id(Id) -> binary_to_list(Id).
|
format_oauth_provider_id(Id) -> binary_to_list(Id).
|
||||||
|
|
||||||
-spec format_oauth_provider(oauth_provider()) -> string().
|
-spec format_oauth_provider(oauth_provider()) -> string().
|
||||||
format_oauth_provider(OAuthProvider) ->
|
format_oauth_provider(OAuthProvider) ->
|
||||||
io_lib:format("{id: ~p, issuer: ~p, token_endpoint: ~p, " ++
|
lists:flatten(io_lib:format("{id: ~p, issuer: ~p, token_endpoint: ~p, " ++
|
||||||
"authorization_endpoint: ~p, end_session_endpoint: ~p, " ++
|
"authorization_endpoint: ~p, end_session_endpoint: ~p, " ++
|
||||||
"jwks_uri: ~p, ssl_options: ~s }", [
|
"jwks_uri: ~p, ssl_options: ~p }", [
|
||||||
format_oauth_provider_id(OAuthProvider#oauth_provider.id),
|
format_oauth_provider_id(OAuthProvider#oauth_provider.id),
|
||||||
OAuthProvider#oauth_provider.issuer,
|
OAuthProvider#oauth_provider.issuer,
|
||||||
OAuthProvider#oauth_provider.token_endpoint,
|
OAuthProvider#oauth_provider.token_endpoint,
|
||||||
OAuthProvider#oauth_provider.authorization_endpoint,
|
OAuthProvider#oauth_provider.authorization_endpoint,
|
||||||
OAuthProvider#oauth_provider.end_session_endpoint,
|
OAuthProvider#oauth_provider.end_session_endpoint,
|
||||||
OAuthProvider#oauth_provider.jwks_uri,
|
OAuthProvider#oauth_provider.jwks_uri,
|
||||||
format_ssl_options(OAuthProvider#oauth_provider.ssl_options)]).
|
format_ssl_options(OAuthProvider#oauth_provider.ssl_options)])).
|
||||||
|
|
|
@ -158,6 +158,31 @@
|
||||||
"rabbitmq_auth_backend_oauth2.authorization_endpoint",
|
"rabbitmq_auth_backend_oauth2.authorization_endpoint",
|
||||||
[{datatype, string}, {validators, ["uri", "https_uri"]}]}.
|
[{datatype, string}, {validators, ["uri", "https_uri"]}]}.
|
||||||
|
|
||||||
|
%% auth_oauth2.authorization_endpoint = https://a.com/authorize
|
||||||
|
%% auth_oauth2.authorization_endpoint.params.resource = ${resource_id}
|
||||||
|
%% auth_oauth2.authorization_endpoint.params.audience = ${resource_id}
|
||||||
|
|
||||||
|
{mapping,
|
||||||
|
"auth_oauth2.authorization_endpoint.params.$param",
|
||||||
|
"rabbitmq_auth_backend_oauth2.authorization_endpoint.req_params",
|
||||||
|
[{datatype, string}]}.
|
||||||
|
|
||||||
|
{translation, "rabbitmq_auth_backend_oauth2.authorization_endpoint.req_params",
|
||||||
|
fun(Conf) ->
|
||||||
|
Settings = cuttlefish_variable:filter_by_prefix("auth_oauth2.authorization_endpoint.req_params", Conf),
|
||||||
|
rabbit_oauth2_schema:translate_endpoint_req_params(Settings)
|
||||||
|
end}.
|
||||||
|
|
||||||
|
{mapping,
|
||||||
|
"auth_oauth2.oauth_providers.$name.algorithms.$algorithm",
|
||||||
|
"rabbitmq_auth_backend_oauth2.oauth_providers",
|
||||||
|
[{datatype, string}]}.
|
||||||
|
|
||||||
|
{translation, "rabbitmq_auth_backend_oauth2.oauth_providers",
|
||||||
|
fun(Conf) ->
|
||||||
|
rabbit_oauth2_schema:translate_oauth_providers(Conf)
|
||||||
|
end}.
|
||||||
|
|
||||||
{mapping,
|
{mapping,
|
||||||
"auth_oauth2.https.peer_verification",
|
"auth_oauth2.https.peer_verification",
|
||||||
"rabbitmq_auth_backend_oauth2.key_config.peer_verification",
|
"rabbitmq_auth_backend_oauth2.key_config.peer_verification",
|
||||||
|
@ -333,5 +358,5 @@
|
||||||
|
|
||||||
{translation, "rabbitmq_auth_backend_oauth2.resource_servers",
|
{translation, "rabbitmq_auth_backend_oauth2.resource_servers",
|
||||||
fun(Conf) ->
|
fun(Conf) ->
|
||||||
rabbit_oauth2_schema:translate_resource_servers(Conf)
|
rabbit_oauth2_schema:translate_resource_servers(Conf)
|
||||||
end}.
|
end}.
|
||||||
|
|
|
@ -11,7 +11,8 @@
|
||||||
-export([
|
-export([
|
||||||
translate_oauth_providers/1,
|
translate_oauth_providers/1,
|
||||||
translate_resource_servers/1,
|
translate_resource_servers/1,
|
||||||
translate_signing_keys/1
|
translate_signing_keys/1,
|
||||||
|
translate_endpoint_req_params/1
|
||||||
]).
|
]).
|
||||||
|
|
||||||
extract_key_as_binary({Name,_}) -> list_to_binary(Name).
|
extract_key_as_binary({Name,_}) -> list_to_binary(Name).
|
||||||
|
@ -63,6 +64,10 @@ translate_list_of_signing_keys(ListOfKidPath) ->
|
||||||
end,
|
end,
|
||||||
maps:map(fun(_K, Path) -> {pem, TryReadingFileFun(Path)} end, maps:from_list(ListOfKidPath)).
|
maps:map(fun(_K, Path) -> {pem, TryReadingFileFun(Path)} end, maps:from_list(ListOfKidPath)).
|
||||||
|
|
||||||
|
-spec translate_endpoint_req_params([{list(), binary()}]) -> map().
|
||||||
|
translate_endpoint_req_params(ListOfReqParams) ->
|
||||||
|
lists:map(fun({Id, Value}) -> {list_to_binary(lists:last(Id)), Value} end, ListOfReqParams).
|
||||||
|
|
||||||
validator_file_exists(Attr, Filename) ->
|
validator_file_exists(Attr, Filename) ->
|
||||||
case file:read_file(Filename) of
|
case file:read_file(Filename) of
|
||||||
{ok, _} ->
|
{ok, _} ->
|
||||||
|
|
|
@ -32,7 +32,7 @@ add_signing_key(KeyId, Type, Value) ->
|
||||||
-spec update_jwks_signing_keys(oauth_provider()) -> ok | {error, term()}.
|
-spec update_jwks_signing_keys(oauth_provider()) -> ok | {error, term()}.
|
||||||
update_jwks_signing_keys(#oauth_provider{id = Id, jwks_uri = JwksUrl,
|
update_jwks_signing_keys(#oauth_provider{id = Id, jwks_uri = JwksUrl,
|
||||||
ssl_options = SslOptions}) ->
|
ssl_options = SslOptions}) ->
|
||||||
rabbit_log:debug("OAuth 2 JWT: downloading keys from ~tp (TLS options: ~p)",
|
rabbit_log:debug("Downloading signing keys from ~tp (TLS options: ~p)",
|
||||||
[JwksUrl, SslOptions]),
|
[JwksUrl, SslOptions]),
|
||||||
case uaa_jwks:get(JwksUrl, SslOptions) of
|
case uaa_jwks:get(JwksUrl, SslOptions) of
|
||||||
{ok, {_, _, JwksBody}} ->
|
{ok, {_, _, JwksBody}} ->
|
||||||
|
@ -40,13 +40,13 @@ update_jwks_signing_keys(#oauth_provider{id = Id, jwks_uri = JwksUrl,
|
||||||
jose:decode(erlang:iolist_to_binary(JwksBody)), []),
|
jose:decode(erlang:iolist_to_binary(JwksBody)), []),
|
||||||
Keys = maps:from_list(lists:map(fun(Key) ->
|
Keys = maps:from_list(lists:map(fun(Key) ->
|
||||||
{maps:get(<<"kid">>, Key, undefined), {json, Key}} end, KeyList)),
|
{maps:get(<<"kid">>, Key, undefined), {json, Key}} end, KeyList)),
|
||||||
rabbit_log:debug("OAuth 2 JWT: downloaded keys ~tp", [Keys]),
|
rabbit_log:debug("Downloaded signing keys ~tp", [Keys]),
|
||||||
case rabbit_oauth2_config:replace_signing_keys(Keys, Id) of
|
case rabbit_oauth2_config:replace_signing_keys(Keys, Id) of
|
||||||
{error, _} = Err -> Err;
|
{error, _} = Err -> Err;
|
||||||
_ -> ok
|
_ -> ok
|
||||||
end;
|
end;
|
||||||
{error, _} = Err ->
|
{error, _} = Err ->
|
||||||
rabbit_log:error("OAuth 2 JWT: failed to download keys: ~tp", [Err]),
|
rabbit_log:error("Failed to download signing keys: ~tp", [Err]),
|
||||||
Err
|
Err
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -56,29 +56,31 @@ decode_and_verify(Token) ->
|
||||||
{error, _} = Err ->
|
{error, _} = Err ->
|
||||||
Err;
|
Err;
|
||||||
ResourceServerId ->
|
ResourceServerId ->
|
||||||
OAuthProviderId =
|
decode_and_verify(Token, ResourceServerId,
|
||||||
rabbit_oauth2_config:get_oauth_provider_id_for_resource_server_id(ResourceServerId),
|
rabbit_oauth2_config:get_oauth_provider_id_for_resource_server_id(
|
||||||
rabbit_log:debug("OAuth 2 JWT: resolved resource_server_id: ~p oauth_provider_id: ~p",
|
ResourceServerId))
|
||||||
[ResourceServerId, OAuthProviderId]),
|
|
||||||
case uaa_jwt_jwt:get_key_id(rabbit_oauth2_config:get_default_key(OAuthProviderId), Token) of
|
|
||||||
{ok, KeyId} ->
|
|
||||||
rabbit_log:debug("OAuth 2 JWT: signing_key_id : '~tp'", [KeyId]),
|
|
||||||
case get_jwk(KeyId, OAuthProviderId) of
|
|
||||||
{ok, JWK} ->
|
|
||||||
case uaa_jwt_jwt:decode_and_verify(
|
|
||||||
OAuthProviderId,
|
|
||||||
JWK,
|
|
||||||
Token) of
|
|
||||||
{true, Payload} -> {true, ResourceServerId, Payload};
|
|
||||||
{false, Payload} -> {false, ResourceServerId, Payload}
|
|
||||||
end;
|
|
||||||
{error, _} = Err ->
|
|
||||||
Err
|
|
||||||
end;
|
|
||||||
{error, _} = Err -> Err
|
|
||||||
end
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
decode_and_verify(Token, ResourceServerId, OAuthProviderId) ->
|
||||||
|
rabbit_log:debug("Resolved resource_server_id: ~p -> oauth_provider_id: ~p",
|
||||||
|
[ResourceServerId, OAuthProviderId]),
|
||||||
|
case uaa_jwt_jwt:get_key_id(rabbit_oauth2_config:get_default_key(OAuthProviderId), Token) of
|
||||||
|
{ok, KeyId} ->
|
||||||
|
case get_jwk(KeyId, OAuthProviderId) of
|
||||||
|
{ok, JWK} ->
|
||||||
|
Algorithms = rabbit_oauth2_config:get_algorithms(OAuthProviderId),
|
||||||
|
rabbit_log:debug("Verifying signature using signing_key_id : '~tp' and algorithms: ~p",
|
||||||
|
[KeyId, Algorithms]),
|
||||||
|
case uaa_jwt_jwt:decode_and_verify(Algorithms, JWK, Token) of
|
||||||
|
{true, Payload} -> {true, ResourceServerId, Payload};
|
||||||
|
{false, Payload} -> {false, ResourceServerId, Payload}
|
||||||
|
end;
|
||||||
|
{error, _} = Err ->
|
||||||
|
Err
|
||||||
|
end;
|
||||||
|
{error, _} = Err -> Err
|
||||||
|
end.
|
||||||
|
|
||||||
resolve_resource_server_id(Token) ->
|
resolve_resource_server_id(Token) ->
|
||||||
case uaa_jwt_jwt:get_aud(Token) of
|
case uaa_jwt_jwt:get_aud(Token) of
|
||||||
{error, _} = Error ->
|
{error, _} = Error ->
|
||||||
|
|
|
@ -12,18 +12,17 @@
|
||||||
-include_lib("jose/include/jose_jws.hrl").
|
-include_lib("jose/include/jose_jws.hrl").
|
||||||
|
|
||||||
|
|
||||||
decode_and_verify(OauthProviderId, Jwk, Token) ->
|
-spec decode_and_verify(list() | undefined, map(), binary()) -> {boolean(), map()}.
|
||||||
Verify =
|
decode_and_verify(Algs, Jwk, Token) ->
|
||||||
case rabbit_oauth2_config:get_algorithms(OauthProviderId) of
|
Verify = case Algs of
|
||||||
undefined -> jose_jwt:verify(Jwk, Token);
|
undefined -> jose_jwt:verify(Jwk, Token);
|
||||||
Algs -> jose_jwt:verify_strict(Jwk, Algs, Token)
|
_ -> jose_jwt:verify_strict(Jwk, Algs, Token)
|
||||||
end,
|
end,
|
||||||
case Verify of
|
case Verify of
|
||||||
{true, #jose_jwt{fields = Fields}, _} -> {true, Fields};
|
{true, #jose_jwt{fields = Fields}, _} -> {true, Fields};
|
||||||
{false, #jose_jwt{fields = Fields}, _} -> {false, Fields}
|
{false, #jose_jwt{fields = Fields}, _} -> {false, Fields}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
get_key_id(DefaultKey, Token) ->
|
get_key_id(DefaultKey, Token) ->
|
||||||
try
|
try
|
||||||
case jose_jwt:peek_protected(Token) of
|
case jose_jwt:peek_protected(Token) of
|
||||||
|
|
|
@ -52,6 +52,7 @@ start_local_rabbitmq() {
|
||||||
init_rabbitmq
|
init_rabbitmq
|
||||||
|
|
||||||
RABBITMQ_SERVER_ROOT=$(realpath ../)
|
RABBITMQ_SERVER_ROOT=$(realpath ../)
|
||||||
|
|
||||||
MOUNT_RABBITMQ_CONF="/etc/rabbitmq/rabbitmq.conf"
|
MOUNT_RABBITMQ_CONF="/etc/rabbitmq/rabbitmq.conf"
|
||||||
MOUNT_ADVANCED_CONFIG="/etc/rabbitmq/advanced.config"
|
MOUNT_ADVANCED_CONFIG="/etc/rabbitmq/advanced.config"
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export IMPORT_DIR=test/authnz-msg-protocols/imports
|
export IMPORT_DIR=selenium/test/authnz-msg-protocols/imports
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export IMPORT_DIR=deps/rabbitmq_management/selenium/test/basic-auth/imports
|
export IMPORT_DIR=selenium/test/basic-auth/imports
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
auth_backends.1 = rabbit_auth_backend_internal
|
auth_backends.1 = rabbit_auth_backend_internal
|
||||||
|
|
||||||
management.login_session_timeout = 1
|
management.login_session_timeout = 1
|
||||||
load_definitions = ${IMPORT_DIR}/users.json
|
load_definitions = ${RABBITMQ_TEST_DIR}/imports/users.json
|
||||||
|
|
||||||
loopback_users = none
|
loopback_users = none
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export OAUTH_SERVER_CONFIG_BASEDIR=deps/rabbitmq_management/selenium/test
|
export OAUTH_SERVER_CONFIG_BASEDIR=test
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
export DEVKEYCLOAK_URL=https://localhost:8442/realms/dev
|
export DEVKEYCLOAK_URL=https://localhost:8442/realms/dev
|
||||||
export DEVKEYCLOAK_CA_CERT=deps/rabbitmq_management/selenium/test/multi-oauth/devkeycloak/ca_certificate.pem
|
export DEVKEYCLOAK_CA_CERT=test/multi-oauth/devkeycloak/ca_certificate.pem
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
export PRODKEYCLOAK_URL=https://localhost:8443/realms/prod
|
export PRODKEYCLOAK_URL=https://localhost:8443/realms/prod
|
||||||
export PRODKEYCLOAK_CA_CERT=deps/rabbitmq_management/selenium/test/multi-oauth/prodkeycloak/ca_certificate.pem
|
export PRODKEYCLOAK_CA_CERT=test/multi-oauth/prodkeycloak/ca_certificate.pem
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export OAUTH_SERVER_CONFIG_BASEDIR=selenium/test
|
export OAUTH_SERVER_CONFIG_BASEDIR=test
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
export KEYCLOAK_URL=https://localhost:8443/realms/test
|
export KEYCLOAK_URL=https://localhost:8443/realms/test
|
||||||
export OAUTH_PROVIDER_URL=https://localhost:8443/realms/test
|
export OAUTH_PROVIDER_URL=https://localhost:8443/realms/test
|
||||||
export OAUTH_PROVIDER_CA_CERT=deps/rabbitmq_management/selenium/test/oauth/keycloak/ca_certificate.pem
|
export OAUTH_PROVIDER_CA_CERT=test/oauth/keycloak/ca_certificate.pem
|
||||||
|
|
Loading…
Reference in New Issue