Skip to content

Commit 2586207

Browse files
Deprecate jwks_url but it is still supported
jwks_uri takes precedence when both are set
1 parent 9a9a449 commit 2586207

File tree

8 files changed

+105
-48
lines changed

8 files changed

+105
-48
lines changed

deps/oauth2_client/src/oauth2_client.erl

Lines changed: 9 additions & 11 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_uri, JwksEndPoint} | proplists:delete(jwks_uri, 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_uri, Map, undefined),
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),

deps/oauth2_client/test/system_SUITE.erl

Lines changed: 60 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,20 @@ all() ->
2828
{group, https_down},
2929
{group, https},
3030
{group, with_all_oauth_provider_settings}
31+
% {group, without_all_oauth_providers_settings}
3132

3233
].
3334

3435
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,6 +81,8 @@ groups() ->
7881

7982
init_per_suite(Config) ->
8083
[
84+
{jwks_url, build_jwks_uri("https", "/certs4url")},
85+
{jwks_uri, build_jwks_uri("https")},
8186
{denies_access_token, [ {token_endpoint, denies_access_token_expectation()} ]},
8287
{auth_server_error, [ {token_endpoint, auth_server_error_when_access_token_request_expectation()} ]},
8388
{non_json_payload, [ {token_endpoint, non_json_payload_when_access_token_request_expectation()} ]},
@@ -95,7 +100,7 @@ init_per_group(https, Config) ->
95100
CertsDir = ?config(rmq_certsdir, Config0),
96101
CaCertFile = filename:join([CertsDir, "testca", "cacert.pem"]),
97102
WrongCaCertFile = filename:join([CertsDir, "server", "server.pem"]),
98-
[{group, https},
103+
[{group, https},
99104
{oauth_provider_id, <<"uaa">>},
100105
{oauth_provider, build_https_oauth_provider(<<"uaa">>, CaCertFile)},
101106
{oauth_provider_with_issuer, keep_only_issuer_and_ssl_options(
@@ -198,17 +203,34 @@ configure_all_oauth_provider_settings(Config) ->
198203
OAuthProvider#oauth_provider.end_session_endpoint),
199204
application:set_env(rabbitmq_auth_backend_oauth2, authorization_endpoint,
200205
OAuthProvider#oauth_provider.authorization_endpoint),
201-
KeyConfig = [ { jwks_uri, OAuthProvider#oauth_provider.jwks_uri } ] ++
206+
KeyConfig0 =
202207
case OAuthProvider#oauth_provider.ssl_options of
203208
undefined ->
204209
[];
205210
_ ->
206211
[ {peer_verification, proplists:get_value(verify,
207212
OAuthProvider#oauth_provider.ssl_options) },
208-
{cacertfile, proplists:get_value(cacertfile,
213+
{cacertfile, proplists:get_value(cacertfile,
209214
OAuthProvider#oauth_provider.ssl_options) }
210215
]
211216
end,
217+
KeyConfig =
218+
case ?config(jwks_uri_type_of_config, Config) of
219+
undefined ->
220+
application:set_env(rabbitmq_auth_backend_oauth2, jwks_uri,
221+
OAuthProvider#oauth_provider.jwks_uri),
222+
KeyConfig0;
223+
only_jwks_uri ->
224+
application:set_env(rabbitmq_auth_backend_oauth2, jwks_uri,
225+
OAuthProvider#oauth_provider.jwks_uri),
226+
KeyConfig0;
227+
only_jwks_url ->
228+
[ { jwks_url, ?config(jwks_url, Config) } | KeyConfig0 ];
229+
both ->
230+
application:set_env(rabbitmq_auth_backend_oauth2, jwks_uri,
231+
OAuthProvider#oauth_provider.jwks_uri),
232+
[ { jwks_url, ?config(jwks_url, Config) } | KeyConfig0 ]
233+
end,
212234
application:set_env(rabbitmq_auth_backend_oauth2, key_config, KeyConfig).
213235

214236
configure_minimum_oauth_provider_settings(Config) ->
@@ -232,9 +254,18 @@ configure_minimum_oauth_provider_settings(Config) ->
232254
end,
233255
application:set_env(rabbitmq_auth_backend_oauth2, key_config, KeyConfig).
234256

235-
init_per_testcase(TestCase, Config) ->
257+
init_per_testcase(TestCase, Config0) ->
236258
application:set_env(rabbitmq_auth_backend_oauth2, use_global_locks, false),
237259

260+
Config = [case TestCase of
261+
jwks_url_is_used_in_absense_of_jwks_uri ->
262+
{jwks_uri_type_of_config, only_jwks_url};
263+
jwks_uri_takes_precedence_over_jwks_url ->
264+
{jwks_uri_type_of_config, both};
265+
_ ->
266+
{jwks_uri_type_of_config, only_jwks_uri}
267+
end | Config0],
268+
238269
case ?config(with_all_oauth_provider_settings, Config) of
239270
false -> configure_minimum_oauth_provider_settings(Config);
240271
true -> configure_all_oauth_provider_settings(Config);
@@ -256,6 +287,7 @@ init_per_testcase(TestCase, Config) ->
256287
end_per_testcase(_, Config) ->
257288
application:unset_env(rabbitmq_auth_backend_oauth2, oauth_providers),
258289
application:unset_env(rabbitmq_auth_backend_oauth2, issuer),
290+
application:unset_env(rabbitmq_auth_backend_oauth2, jwks_uri),
259291
application:unset_env(rabbitmq_auth_backend_oauth2, token_endpoint),
260292
application:unset_env(rabbitmq_auth_backend_oauth2, authorization_endpoint),
261293
application:unset_env(rabbitmq_auth_backend_oauth2, end_session_endpoint),
@@ -466,16 +498,15 @@ ssl_connection_error(Config) ->
466498
{error, {failed_connect, _} } = oauth2_client:get_access_token(
467499
?config(oauth_provider_with_wrong_ca, Config), build_access_token_request(Parameters)).
468500

469-
verify_get_oauth_provider_returns_oauth_provider_from_key_config() ->
501+
verify_get_oauth_provider_returns_root_oauth_provider() ->
470502
{ok, #oauth_provider{id = Id,
471503
issuer = Issuer,
472504
token_endpoint = TokenEndPoint,
473505
jwks_uri = Jwks_uri}} =
474506
oauth2_client:get_oauth_provider([issuer, token_endpoint, jwks_uri]),
475507
ExpectedIssuer = application:get_env(rabbitmq_auth_backend_oauth2, issuer, undefined),
476508
ExpectedTokenEndPoint = application:get_env(rabbitmq_auth_backend_oauth2, token_endpoint, undefined),
477-
ExpectedJwks_uri = proplists:get_value(jwks_uri,
478-
application:get_env(rabbitmq_auth_backend_oauth2, key_config, [])),
509+
ExpectedJwks_uri = application:get_env(rabbitmq_auth_backend_oauth2, jwks_uri, undefined),
479510
?assertEqual(root, Id),
480511
?assertEqual(ExpectedIssuer, Issuer),
481512
?assertEqual(ExpectedTokenEndPoint, TokenEndPoint),
@@ -494,7 +525,7 @@ get_oauth_provider(Config) ->
494525
true ->
495526
case application:get_env(rabbitmq_auth_backend_oauth2, default_oauth_provider, undefined) of
496527
undefined ->
497-
verify_get_oauth_provider_returns_oauth_provider_from_key_config();
528+
verify_get_oauth_provider_returns_root_oauth_provider();
498529
DefaultOAuthProviderId ->
499530
verify_get_oauth_provider_returns_default_oauth_provider(DefaultOAuthProviderId)
500531
end;
@@ -564,6 +595,20 @@ get_oauth_provider_given_oauth_provider_id(Config) ->
564595
Jwks_uri)
565596
end.
566597

598+
jwks_url_is_used_in_absense_of_jwks_uri(Config) ->
599+
{ok, #oauth_provider{
600+
jwks_uri = Jwks_uri}} = oauth2_client:get_oauth_provider([jwks_uri]),
601+
?assertEqual(
602+
proplists:get_value(jwks_url,
603+
application:get_env(rabbitmq_auth_backend_oauth2, key_config, []), undefined),
604+
Jwks_uri).
605+
606+
jwks_uri_takes_precedence_over_jwks_url(Config) ->
607+
{ok, #oauth_provider{
608+
jwks_uri = Jwks_uri}} = oauth2_client:get_oauth_provider([jwks_uri]),
609+
?assertEqual(
610+
application:get_env(rabbitmq_auth_backend_oauth2, jwks_uri, undefined),
611+
Jwks_uri).
567612

568613

569614
%%% HELPERS
@@ -584,10 +629,13 @@ build_token_endpoint_uri(Scheme) ->
584629
path => "/token"}).
585630

586631
build_jwks_uri(Scheme) ->
632+
build_jwks_uri(Scheme, "/certs").
633+
634+
build_jwks_uri(Scheme, Path) ->
587635
uri_string:recompose(#{scheme => Scheme,
588636
host => "localhost",
589637
port => rabbit_data_coercion:to_integer(?AUTH_PORT),
590-
path => "/certs"}).
638+
path => Path}).
591639

592640
build_access_token_request(Request) ->
593641
#access_token_request {

deps/rabbitmq_auth_backend_oauth2/README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,13 @@ In that case, the configuration would look like this:
149149
{rabbitmq_auth_backend_oauth2, [
150150
{resource_server_id, <<"my_rabbit_server">>},
151151
{key_config, [
152-
{jwks_url, <<"https://jwt-issuer.my-domain.local/jwks.json">>}
152+
{jwks_uri, <<"https://jwt-issuer.my-domain.local/jwks.json">>}
153153
]}
154154
]},
155155
].
156156
```
157157

158-
Note: if both are configured, `jwks_url` takes precedence over `signing_keys`.
158+
Note: if both are configured, `jwks_uri` takes precedence over `signing_keys`.
159159

160160
### Variables Configurable in rabbitmq.conf
161161

@@ -166,7 +166,7 @@ Note: if both are configured, `jwks_url` takes precedence over `signing_keys`.
166166
| `auth_oauth2.additional_scopes_key` | Key to fetch additional scopes from (maps to `additional_rabbitmq_scopes` in the `advanced.config` format)
167167
| `auth_oauth2.default_key` | ID (name) of the default signing key
168168
| `auth_oauth2.signing_keys` | Paths to signing key files
169-
| `auth_oauth2.jwks_url` | The URL of key server. According to the [JWT Specification](https://datatracker.ietf.org/doc/html/rfc7515#section-4.1.2) key server URL must be https
169+
| `auth_oauth2.jwks_uri` | The URL of key server. According to the [JWT Specification](https://datatracker.ietf.org/doc/html/rfc7515#section-4.1.2) key server URL must be https
170170
| `auth_oauth2.https.cacertfile` | Path to a file containing PEM-encoded CA certificates. The CA certificates are used during key server [peer verification](https://rabbitmq.com/ssl.html#peer-verification)
171171
| `auth_oauth2.https.depth` | The maximum number of non-self-issued intermediate certificates that may follow the peer certificate in a valid [certification path](https://rabbitmq.com/ssl.html#peer-verification-depth). Default is 10.
172172
| `auth_oauth2.https.peer_verification` | Should [peer verification](https://rabbitmq.com/ssl.html#peer-verification) be enabled Available values: `verify_none`, `verify_peer`. Default is `verify_none`. It is recommended to configure `verify_peer`. Peer verification requires a certain amount of setup and is more secure.
@@ -194,7 +194,7 @@ auth_oauth2.algorithms.2 = RS256
194194

195195
```
196196
auth_oauth2.resource_server_id = new_resource_server_id
197-
auth_oauth2.jwks_url = https://my-jwt-issuer/jwks.json
197+
auth_oauth2.jwks_uri = https://my-jwt-issuer/jwks.json
198198
auth_oauth2.https.cacertfile = test/config_schema_SUITE_data/certs/cacert.pem
199199
auth_oauth2.https.peer_verification = verify_peer
200200
auth_oauth2.https.depth = 5
@@ -234,7 +234,7 @@ resolve the user's identity: `username`, `user_name`, `email`, `sub`, `client_id
234234
{resource_server_id, <<"my_rabbit_server">>},
235235
{preferred_username_claims, [ <<"username">>, <<"user_name">>, <<"email">> ]}
236236
{key_config, [
237-
{jwks_url, <<"https://jwt-issuer.my-domain.local/jwks.json">>}
237+
{jwks_uri, <<"https://jwt-issuer.my-domain.local/jwks.json">>}
238238
]}
239239
]},
240240
].

deps/rabbitmq_auth_backend_oauth2/priv/schema/rabbitmq_auth_backend_oauth2.schema

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,16 @@
143143
"rabbitmq_auth_backend_oauth2.token_endpoint",
144144
[{datatype, string}, {validators, ["uri", "https_uri"]}]}.
145145

146+
%% DEPRECATES auth_oauth2.jwks_url
146147
{mapping,
147148
"auth_oauth2.jwks_uri",
148-
"rabbitmq_auth_backend_oauth2.key_config.jwks_uri",
149+
"rabbitmq_auth_backend_oauth2.jwks_uri",
150+
[{datatype, string}, {validators, ["uri", "https_uri"]}]}.
151+
152+
%% DEPRECATED
153+
{mapping,
154+
"auth_oauth2.jwks_url",
155+
"rabbitmq_auth_backend_oauth2.key_config.jwks_url",
149156
[{datatype, string}, {validators, ["uri", "https_uri"]}]}.
150157

151158
{mapping,

deps/rabbitmq_auth_backend_oauth2/src/uaa_jwt.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ get_jwk(KeyId, InternalOAuthProvider, AllowUpdateJwks) ->
124124
case update_jwks_signing_keys(OAuthProvider) of
125125
ok ->
126126
get_jwk(KeyId, InternalOAuthProvider, false);
127-
{error, no_jwks_url} ->
127+
{error, no_jwks_uri} ->
128128
{error, key_not_found};
129129
{error, _} = Err ->
130130
Err

deps/rabbitmq_auth_backend_oauth2/test/config_schema_SUITE_data/rabbitmq_auth_backend_oauth2.snippets

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
auth_oauth2.default_key = id1
1212
auth_oauth2.signing_keys.id1 = test/config_schema_SUITE_data/certs/key.pem
1313
auth_oauth2.signing_keys.id2 = test/config_schema_SUITE_data/certs/cert.pem
14+
auth_oauth2.jwks_uri = https://my-jwt-issuer/jwks.json
1415
auth_oauth2.jwks_url = https://my-jwt-issuer/jwks.json
1516
auth_oauth2.issuer = https://my-jwt-issuer
1617
auth_oauth2.https.cacertfile = test/config_schema_SUITE_data/certs/cacert.pem
@@ -36,6 +37,7 @@
3637
{discovery_endpoint_params, [
3738
{<<"param1">>, <<"value1">>}
3839
]},
40+
{jwks_uri, "https://my-jwt-issuer/jwks.json"},
3941
{key_config, [
4042
{default_key, <<"id1">>},
4143
{signing_keys,
@@ -69,6 +71,7 @@
6971
auth_oauth2.default_key = id1
7072
auth_oauth2.signing_keys.id1 = test/config_schema_SUITE_data/certs/key.pem
7173
auth_oauth2.signing_keys.id2 = test/config_schema_SUITE_data/certs/cert.pem
74+
auth_oauth2.jwks_uri = https://my-jwt-issuer/jwks.json
7275
auth_oauth2.jwks_url = https://my-jwt-issuer/jwks.json
7376
auth_oauth2.https.cacertfile = test/config_schema_SUITE_data/certs/cacert.pem
7477
auth_oauth2.https.peer_verification = verify_none
@@ -90,6 +93,7 @@
9093
{extra_scopes_source, <<"my_custom_scope_key">>},
9194
{preferred_username_claims, [<<"user_name">>, <<"username">>, <<"email">>]},
9295
{verify_aud, true},
96+
{jwks_uri, "https://my-jwt-issuer/jwks.json"},
9397
{resource_servers,
9498
#{
9599
<<"rabbitmq-operations">> => [

0 commit comments

Comments
 (0)