Skip to content

Commit 9893a2b

Browse files
Merge pull request #12399 from rabbitmq/deprecate-oauth2-settings
Deprecate two OAuth2 settings: auth_oauth2.jwks_url and management.metadata_url
2 parents 6c50ce2 + 0f1b876 commit 9893a2b

File tree

12 files changed

+350
-254
lines changed

12 files changed

+350
-254
lines changed

deps/oauth2_client/src/oauth2_client.erl

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -215,12 +215,10 @@ do_update_oauth_provider_endpoints_configuration(OAuthProvider) when
215215
undefined -> do_nothing;
216216
EndSessionEndpoint -> set_env(end_session_endpoint, EndSessionEndpoint)
217217
end,
218-
List = get_env(key_config, []),
219-
ModifiedList = case OAuthProvider#oauth_provider.jwks_uri of
220-
undefined -> List;
221-
JwksEndPoint -> [{jwks_url, JwksEndPoint} | proplists:delete(jwks_url, List)]
218+
case OAuthProvider#oauth_provider.jwks_uri of
219+
undefined -> do_nothing;
220+
JwksUri -> set_env(jwks_uri, JwksUri)
222221
end,
223-
set_env(key_config, ModifiedList),
224222
rabbit_log:debug("Updated oauth_provider details: ~p ",
225223
[format_oauth_provider(OAuthProvider)]),
226224
OAuthProvider;
@@ -271,7 +269,7 @@ unlock(LockId) ->
271269
-spec get_oauth_provider(list()) -> {ok, oauth_provider()} | {error, any()}.
272270
get_oauth_provider(ListOfRequiredAttributes) ->
273271
case get_env(default_oauth_provider) of
274-
undefined -> get_oauth_provider_from_keyconfig(ListOfRequiredAttributes);
272+
undefined -> get_root_oauth_provider(ListOfRequiredAttributes);
275273
DefaultOauthProviderId ->
276274
rabbit_log:debug("Using default_oauth_provider ~p",
277275
[DefaultOauthProviderId]),
@@ -303,9 +301,9 @@ ensure_oauth_provider_has_attributes(OAuthProvider, ListOfRequiredAttributes) ->
303301
{error, {missing_oauth_provider_attributes, Attrs}}
304302
end.
305303

306-
get_oauth_provider_from_keyconfig(ListOfRequiredAttributes) ->
307-
OAuthProvider = lookup_oauth_provider_from_keyconfig(),
308-
rabbit_log:debug("Using oauth_provider ~p from keyconfig",
304+
get_root_oauth_provider(ListOfRequiredAttributes) ->
305+
OAuthProvider = lookup_root_oauth_provider(),
306+
rabbit_log:debug("Using root oauth_provider ~p",
309307
[format_oauth_provider(OAuthProvider)]),
310308
case find_missing_attributes(OAuthProvider, ListOfRequiredAttributes) of
311309
[] ->
@@ -384,7 +382,7 @@ find_missing_attributes(#oauth_provider{} = OAuthProvider, RequiredAttributes) -
384382
Filtered = filter_undefined_props(PropList),
385383
intersection(Filtered, RequiredAttributes).
386384

387-
lookup_oauth_provider_from_keyconfig() ->
385+
lookup_root_oauth_provider() ->
388386
Map = maps:from_list(get_env(key_config, [])),
389387
Issuer = get_env(issuer),
390388
DiscoverEndpoint = build_openid_discovery_endpoint(Issuer,
@@ -393,7 +391,7 @@ lookup_oauth_provider_from_keyconfig() ->
393391
id = root,
394392
issuer = Issuer,
395393
discovery_endpoint = DiscoverEndpoint,
396-
jwks_uri = maps:get(jwks_url, Map, undefined), %% jwks_url not uri . _url is the legacy name
394+
jwks_uri = get_env(jwks_uri, maps:get(jwks_url, Map, undefined)),
397395
token_endpoint = get_env(token_endpoint),
398396
authorization_endpoint = get_env(authorization_endpoint),
399397
end_session_endpoint = get_env(end_session_endpoint),
@@ -437,15 +435,17 @@ extract_ssl_options_as_list(Map) ->
437435
++
438436
case maps:get(hostname_verification, Map, none) of
439437
wildcard ->
440-
[{customize_hostname_check, [{match_fun, public_key:pkix_verify_hostname_match_fun(https)}]}];
438+
[{customize_hostname_check, [{match_fun,
439+
public_key:pkix_verify_hostname_match_fun(https)}]}];
441440
none ->
442441
[]
443442
end.
444443

445444
% Replace peer_verification with verify to make it more consistent with other
446445
% ssl_options in RabbitMQ and Erlang's ssl options
447446
% Eventually, peer_verification will be removed. For now, both are allowed
448-
-spec get_verify_or_peer_verification(#{atom() => any()}, verify_none | verify_peer ) -> verify_none | verify_peer.
447+
-spec get_verify_or_peer_verification(#{atom() =>
448+
any()}, verify_none | verify_peer ) -> verify_none | verify_peer.
449449
get_verify_or_peer_verification(Ssl_options, Default) ->
450450
case maps:get(verify, Ssl_options, undefined) of
451451
undefined ->
@@ -464,7 +464,8 @@ lookup_oauth_provider_config(OAuth2ProviderId) ->
464464
undefined ->
465465
{error, {oauth_provider_not_found, OAuth2ProviderId}};
466466
OAuthProvider ->
467-
ensure_oauth_provider_has_id_property(OAuth2ProviderId, OAuthProvider)
467+
ensure_oauth_provider_has_id_property(OAuth2ProviderId,
468+
OAuthProvider)
468469
end;
469470
_ -> {error, invalid_oauth_provider_configuration}
470471
end.
@@ -535,8 +536,9 @@ get_timeout_of_default(Timeout) ->
535536
is_json(?CONTENT_JSON) -> true;
536537
is_json(_) -> false.
537538

538-
-spec decode_body(string(), string() | binary() | term()) -> 'false' | 'null' | 'true' |
539-
binary() | [any()] | number() | map() | {error, term()}.
539+
-spec decode_body(string(), string() | binary() | term()) ->
540+
'false' | 'null' | 'true' | binary() | [any()] | number() | map() |
541+
{error, term()}.
540542

541543
decode_body(_, []) -> [];
542544
decode_body(?CONTENT_JSON, Body) ->
@@ -615,7 +617,8 @@ format_ssl_options(TlsOptions) ->
615617
[] -> 0;
616618
Certs -> length(Certs)
617619
end,
618-
lists:flatten(io_lib:format("{verify: ~p, fail_if_no_peer_cert: ~p, crl_check: ~p, depth: ~p, cacertfile: ~p, cacerts(count): ~p }", [
620+
lists:flatten(io_lib:format("{verify: ~p, fail_if_no_peer_cert: ~p, " ++
621+
"crl_check: ~p, depth: ~p, cacertfile: ~p, cacerts(count): ~p }", [
619622
proplists:get_value(verify, TlsOptions),
620623
proplists:get_value(fail_if_no_peer_cert, TlsOptions),
621624
proplists:get_value(crl_check, TlsOptions),

deps/oauth2_client/test/system_SUITE.erl

Lines changed: 83 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212

1313
-include_lib("oauth2_client.hrl").
1414
-import(oauth2_client, [
15-
build_openid_discovery_endpoint/3]).
15+
build_openid_discovery_endpoint/3
16+
]).
1617

1718
-compile(export_all).
1819

@@ -35,10 +36,12 @@ groups() ->
3536
[
3637

3738
{with_all_oauth_provider_settings, [], [
38-
{group, verify_get_oauth_provider}
39+
{group, verify_get_oauth_provider},
40+
jwks_uri_takes_precedence_over_jwks_url,
41+
jwks_url_is_used_in_absense_of_jwks_uri
3942
]},
4043
{without_all_oauth_providers_settings, [], [
41-
{group, verify_get_oauth_provider}
44+
{group, verify_get_oauth_provider}
4245
]},
4346
{verify_openid_configuration, [], [
4447
get_openid_configuration,
@@ -57,7 +60,7 @@ groups() ->
5760
expiration_time_in_token
5861
]},
5962
{verify_get_oauth_provider, [], [
60-
get_oauth_provider,
63+
get_oauth_provider,
6164
{with_default_oauth_provider, [], [
6265
get_oauth_provider
6366
]},
@@ -78,10 +81,16 @@ groups() ->
7881

7982
init_per_suite(Config) ->
8083
[
81-
{denies_access_token, [ {token_endpoint, denies_access_token_expectation()} ]},
82-
{auth_server_error, [ {token_endpoint, auth_server_error_when_access_token_request_expectation()} ]},
83-
{non_json_payload, [ {token_endpoint, non_json_payload_when_access_token_request_expectation()} ]},
84-
{grants_refresh_token, [ {token_endpoint, grants_refresh_token_expectation()} ]}
84+
{jwks_url, build_jwks_uri("https", "/certs4url")},
85+
{jwks_uri, build_jwks_uri("https")},
86+
{denies_access_token, [
87+
{token_endpoint, denies_access_token_expectation()} ]},
88+
{auth_server_error, [
89+
{token_endpoint, auth_server_error_when_access_token_request_expectation()} ]},
90+
{non_json_payload, [
91+
{token_endpoint, non_json_payload_when_access_token_request_expectation()} ]},
92+
{grants_refresh_token, [
93+
{token_endpoint, grants_refresh_token_expectation()} ]}
8594
| Config].
8695

8796
end_per_suite(Config) ->
@@ -95,7 +104,7 @@ init_per_group(https, Config) ->
95104
CertsDir = ?config(rmq_certsdir, Config0),
96105
CaCertFile = filename:join([CertsDir, "testca", "cacert.pem"]),
97106
WrongCaCertFile = filename:join([CertsDir, "server", "server.pem"]),
98-
[{group, https},
107+
[{group, https},
99108
{oauth_provider_id, <<"uaa">>},
100109
{oauth_provider, build_https_oauth_provider(<<"uaa">>, CaCertFile)},
101110
{oauth_provider_with_issuer, keep_only_issuer_and_ssl_options(
@@ -198,21 +207,38 @@ configure_all_oauth_provider_settings(Config) ->
198207
OAuthProvider#oauth_provider.end_session_endpoint),
199208
application:set_env(rabbitmq_auth_backend_oauth2, authorization_endpoint,
200209
OAuthProvider#oauth_provider.authorization_endpoint),
201-
KeyConfig = [ { jwks_url, OAuthProvider#oauth_provider.jwks_uri } ] ++
210+
KeyConfig0 =
202211
case OAuthProvider#oauth_provider.ssl_options of
203212
undefined ->
204213
[];
205214
_ ->
206215
[ {peer_verification, proplists:get_value(verify,
207216
OAuthProvider#oauth_provider.ssl_options) },
208-
{cacertfile, proplists:get_value(cacertfile,
217+
{cacertfile, proplists:get_value(cacertfile,
209218
OAuthProvider#oauth_provider.ssl_options) }
210219
]
211220
end,
221+
KeyConfig =
222+
case ?config(jwks_uri_type_of_config, Config) of
223+
undefined ->
224+
application:set_env(rabbitmq_auth_backend_oauth2, jwks_uri,
225+
OAuthProvider#oauth_provider.jwks_uri),
226+
KeyConfig0;
227+
only_jwks_uri ->
228+
application:set_env(rabbitmq_auth_backend_oauth2, jwks_uri,
229+
OAuthProvider#oauth_provider.jwks_uri),
230+
KeyConfig0;
231+
only_jwks_url ->
232+
[ { jwks_url, ?config(jwks_url, Config) } | KeyConfig0 ];
233+
both ->
234+
application:set_env(rabbitmq_auth_backend_oauth2, jwks_uri,
235+
OAuthProvider#oauth_provider.jwks_uri),
236+
[ { jwks_url, ?config(jwks_url, Config) } | KeyConfig0 ]
237+
end,
212238
application:set_env(rabbitmq_auth_backend_oauth2, key_config, KeyConfig).
213239

214240
configure_minimum_oauth_provider_settings(Config) ->
215-
OAuthProvider = ?config(oauth_provider_with_issuer, Config),
241+
OAuthProvider = ?config(oauth_provider, Config),
216242
OAuthProviders = #{ ?config(oauth_provider_id, Config) =>
217243
oauth_provider_to_proplist(OAuthProvider) },
218244
application:set_env(rabbitmq_auth_backend_oauth2, oauth_providers,
@@ -232,9 +258,18 @@ configure_minimum_oauth_provider_settings(Config) ->
232258
end,
233259
application:set_env(rabbitmq_auth_backend_oauth2, key_config, KeyConfig).
234260

235-
init_per_testcase(TestCase, Config) ->
261+
init_per_testcase(TestCase, Config0) ->
236262
application:set_env(rabbitmq_auth_backend_oauth2, use_global_locks, false),
237263

264+
Config = [case TestCase of
265+
jwks_url_is_used_in_absense_of_jwks_uri ->
266+
{jwks_uri_type_of_config, only_jwks_url};
267+
jwks_uri_takes_precedence_over_jwks_url ->
268+
{jwks_uri_type_of_config, both};
269+
_ ->
270+
{jwks_uri_type_of_config, only_jwks_uri}
271+
end | Config0],
272+
238273
case ?config(with_all_oauth_provider_settings, Config) of
239274
false -> configure_minimum_oauth_provider_settings(Config);
240275
true -> configure_all_oauth_provider_settings(Config);
@@ -248,6 +283,9 @@ init_per_testcase(TestCase, Config) ->
248283
https ->
249284
start_https_oauth_server(?AUTH_PORT, ?config(rmq_certsdir, Config),
250285
ListOfExpectations);
286+
without_all_oauth_providers_settings ->
287+
start_https_oauth_server(?AUTH_PORT, ?config(rmq_certsdir, Config),
288+
ListOfExpectations);
251289
_ ->
252290
do_nothing
253291
end,
@@ -256,13 +294,16 @@ init_per_testcase(TestCase, Config) ->
256294
end_per_testcase(_, Config) ->
257295
application:unset_env(rabbitmq_auth_backend_oauth2, oauth_providers),
258296
application:unset_env(rabbitmq_auth_backend_oauth2, issuer),
297+
application:unset_env(rabbitmq_auth_backend_oauth2, jwks_uri),
259298
application:unset_env(rabbitmq_auth_backend_oauth2, token_endpoint),
260299
application:unset_env(rabbitmq_auth_backend_oauth2, authorization_endpoint),
261300
application:unset_env(rabbitmq_auth_backend_oauth2, end_session_endpoint),
262301
application:unset_env(rabbitmq_auth_backend_oauth2, key_config),
263302
case ?config(group, Config) of
264303
https ->
265304
stop_https_auth_server();
305+
without_all_oauth_providers_settings ->
306+
stop_https_auth_server();
266307
_ ->
267308
do_nothing
268309
end,
@@ -466,16 +507,15 @@ ssl_connection_error(Config) ->
466507
{error, {failed_connect, _} } = oauth2_client:get_access_token(
467508
?config(oauth_provider_with_wrong_ca, Config), build_access_token_request(Parameters)).
468509

469-
verify_get_oauth_provider_returns_oauth_provider_from_key_config() ->
510+
verify_get_oauth_provider_returns_root_oauth_provider() ->
470511
{ok, #oauth_provider{id = Id,
471512
issuer = Issuer,
472513
token_endpoint = TokenEndPoint,
473514
jwks_uri = Jwks_uri}} =
474515
oauth2_client:get_oauth_provider([issuer, token_endpoint, jwks_uri]),
475-
ExpectedIssuer = application:get_env(rabbitmq_auth_backend_oauth2, issuer, undefined),
476-
ExpectedTokenEndPoint = application:get_env(rabbitmq_auth_backend_oauth2, token_endpoint, undefined),
477-
ExpectedJwks_uri = proplists:get_value(jwks_url,
478-
application:get_env(rabbitmq_auth_backend_oauth2, key_config, [])),
516+
ExpectedIssuer = get_env(issuer),
517+
ExpectedTokenEndPoint = get_env(token_endpoint),
518+
ExpectedJwks_uri = get_env(jwks_uri),
479519
?assertEqual(root, Id),
480520
?assertEqual(ExpectedIssuer, Issuer),
481521
?assertEqual(ExpectedTokenEndPoint, TokenEndPoint),
@@ -492,9 +532,9 @@ verify_get_oauth_provider_returns_default_oauth_provider(DefaultOAuthProviderId)
492532
get_oauth_provider(Config) ->
493533
case ?config(with_all_oauth_provider_settings, Config) of
494534
true ->
495-
case application:get_env(rabbitmq_auth_backend_oauth2, default_oauth_provider, undefined) of
535+
case get_env(default_oauth_provider) of
496536
undefined ->
497-
verify_get_oauth_provider_returns_oauth_provider_from_key_config();
537+
verify_get_oauth_provider_returns_root_oauth_provider();
498538
DefaultOAuthProviderId ->
499539
verify_get_oauth_provider_returns_default_oauth_provider(DefaultOAuthProviderId)
500540
end;
@@ -525,8 +565,7 @@ get_oauth_provider_given_oauth_provider_id(Config) ->
525565
[issuer, token_endpoint, jwks_uri, authorization_endpoint,
526566
end_session_endpoint]),
527567

528-
OAuthProviders = application:get_env(rabbitmq_auth_backend_oauth2,
529-
oauth_providers, #{}),
568+
OAuthProviders = get_env(oauth_providers, #{}),
530569
ExpectedProvider = maps:get(Id, OAuthProviders, []),
531570
?assertEqual(proplists:get_value(issuer, ExpectedProvider),
532571
Issuer),
@@ -564,6 +603,17 @@ get_oauth_provider_given_oauth_provider_id(Config) ->
564603
Jwks_uri)
565604
end.
566605

606+
jwks_url_is_used_in_absense_of_jwks_uri(Config) ->
607+
{ok, #oauth_provider{
608+
jwks_uri = Jwks_uri}} = oauth2_client:get_oauth_provider([jwks_uri]),
609+
?assertEqual(
610+
proplists:get_value(jwks_url, get_env(key_config, []), undefined),
611+
Jwks_uri).
612+
613+
jwks_uri_takes_precedence_over_jwks_url(Config) ->
614+
{ok, #oauth_provider{
615+
jwks_uri = Jwks_uri}} = oauth2_client:get_oauth_provider([jwks_uri]),
616+
?assertEqual(get_env(jwks_uri), Jwks_uri).
567617

568618

569619
%%% HELPERS
@@ -584,10 +634,13 @@ build_token_endpoint_uri(Scheme) ->
584634
path => "/token"}).
585635

586636
build_jwks_uri(Scheme) ->
637+
build_jwks_uri(Scheme, "/certs").
638+
639+
build_jwks_uri(Scheme, Path) ->
587640
uri_string:recompose(#{scheme => Scheme,
588641
host => "localhost",
589642
port => rabbit_data_coercion:to_integer(?AUTH_PORT),
590-
path => "/certs"}).
643+
path => Path}).
591644

592645
build_access_token_request(Request) ->
593646
#access_token_request {
@@ -623,11 +676,11 @@ oauth_provider_to_proplist(#oauth_provider{
623676
authorization_endpoint = AuthorizationEndpoint,
624677
ssl_options = SslOptions,
625678
jwks_uri = Jwks_uri}) ->
626-
[ { issuer, Issuer},
679+
[ {issuer, Issuer},
627680
{token_endpoint, TokenEndpoint},
628681
{end_session_endpoint, EndSessionEndpoint},
629682
{authorization_endpoint, AuthorizationEndpoint},
630-
{ https,
683+
{https,
631684
case SslOptions of
632685
undefined -> [];
633686
Value -> Value
@@ -677,6 +730,11 @@ token(ExpiresIn) ->
677730
EncodedToken.
678731

679732

733+
get_env(Par) ->
734+
application:get_env(rabbitmq_auth_backend_oauth2, Par, undefined).
735+
get_env(Par, Default) ->
736+
application:get_env(rabbitmq_auth_backend_oauth2, Par, Default).
737+
680738

681739
build_http_mock_behaviour(Request, Response) ->
682740
#{request => Request, response => Response}.

0 commit comments

Comments
 (0)