Skip to content

Commit f9704cc

Browse files
Deprecate oauth_metadata_url
If oauth_metadata_url is configured, RabbitMQ uses it. Else it uses the discovery_endpoint url calculated from issuer and discovery_endpoint_path
1 parent 4647aff commit f9704cc

File tree

3 files changed

+208
-132
lines changed

3 files changed

+208
-132
lines changed

deps/rabbitmq_management/priv/schema/rabbitmq_management.schema

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,13 @@ end}.
472472
{mapping, "management.oauth_response_type", "rabbitmq_management.oauth_response_type",
473473
[{datatype, string}]}.
474474

475+
%% THIS VARIABLE IS DEPRECATED. CHECKOUT auth_oauth2.discovery_endpoint_path VARIABLE.
476+
%% The URL of the OIDC discovery url where the provider is listening on
477+
%% by default it is <oauth_provider_url>/.well-known/openid-configuration which is the
478+
%% default OIDC discovery endpoint
479+
{mapping, "management.oauth_metadata_url", "rabbitmq_management.oauth_metadata_url",
480+
[{datatype, string}]}.
481+
475482
%% Configure OAuth2 authorization_endpoint additional request parameters
476483
{mapping, "management.oauth_authorization_endpoint_params.$name",
477484
"rabbitmq_management.oauth_authorization_endpoint_params",
@@ -552,6 +559,12 @@ end}.
552559
[{datatype, string}]
553560
}.
554561

562+
{mapping,
563+
"management.oauth_resource_servers.$name.oauth_metadata_url",
564+
"rabbitmq_management.oauth_resource_servers",
565+
[{datatype, string}]
566+
}.
567+
555568
{mapping,
556569
"management.oauth_resource_servers.$name.oauth_initiated_logon_type",
557570
"rabbitmq_management.oauth_resource_servers",

deps/rabbitmq_management/src/rabbit_mgmt_wm_auth.erl

Lines changed: 167 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -23,162 +23,199 @@ variances(Req, Context) ->
2323
{[<<"accept-encoding">>, <<"origin">>], Req, Context}.
2424

2525
content_types_provided(ReqData, Context) ->
26-
{rabbit_mgmt_util:responder_map(to_json), ReqData, Context}.
26+
{rabbit_mgmt_util:responder_map(to_json), ReqData, Context}.
2727

2828
merge_property(Key, List, MapIn) ->
29-
case proplists:get_value(Key, List) of
30-
undefined -> MapIn;
31-
V0 -> MapIn#{Key => V0}
32-
end.
29+
case proplists:get_value(Key, List) of
30+
undefined -> MapIn;
31+
V0 -> MapIn#{Key => V0}
32+
end.
3333

3434
extract_oauth_provider_info_props_as_map(ManagementProps) ->
35-
lists:foldl(fun(K, Acc) ->
36-
merge_property(K, ManagementProps, Acc) end, #{}, [oauth_provider_url,
37-
oauth_authorization_endpoint_params,
38-
oauth_token_endpoint_params]).
39-
40-
merge_oauth_provider_info(OAuthResourceServer, MgtResourceServer, ManagementProps) ->
41-
OAuthProviderResult = case proplists:get_value(oauth_provider_id, OAuthResourceServer) of
42-
undefined -> oauth2_client:get_oauth_provider([issuer]);
43-
OauthProviderId -> oauth2_client:get_oauth_provider(OauthProviderId, [issuer])
44-
end,
45-
OAuthProviderInfo0 = case OAuthProviderResult of
46-
{ok, OAuthProvider} -> oauth_provider_to_map(OAuthProvider);
47-
{error, _} -> #{}
48-
end,
49-
OAuthProviderInfo1 = maps:merge(OAuthProviderInfo0,
50-
extract_oauth_provider_info_props_as_map(ManagementProps)),
51-
maps:merge(OAuthProviderInfo1, proplists:to_map(MgtResourceServer)).
35+
lists:foldl(fun(K, Acc) ->
36+
merge_property(K, ManagementProps, Acc) end, #{},
37+
[oauth_provider_url,
38+
oauth_metadata_url,
39+
oauth_authorization_endpoint_params,
40+
oauth_token_endpoint_params]).
41+
42+
merge_oauth_provider_info(OAuthResourceServer, MgtResourceServer,
43+
ManagementProps) ->
44+
OAuthProviderResult =
45+
case proplists:get_value(oauth_provider_id, OAuthResourceServer) of
46+
undefined ->
47+
oauth2_client:get_oauth_provider([issuer]);
48+
OauthProviderId ->
49+
oauth2_client:get_oauth_provider(OauthProviderId, [issuer])
50+
end,
51+
OAuthProviderInfo0 =
52+
case OAuthProviderResult of
53+
{ok, OAuthProvider} -> oauth_provider_to_map(OAuthProvider);
54+
{error, _} -> #{}
55+
end,
56+
OAuthProviderInfo1 = maps:merge(OAuthProviderInfo0,
57+
extract_oauth_provider_info_props_as_map(ManagementProps)),
58+
maps:merge(OAuthProviderInfo1, proplists:to_map(MgtResourceServer)).
5259

5360
oauth_provider_to_map(OAuthProvider) ->
54-
% only include issuer and end_session_endpoint for now. The other endpoints are resolved by oidc-client library
55-
Map0 = case OAuthProvider#oauth_provider.issuer of
56-
undefined -> #{};
57-
Issuer -> #{ oauth_provider_url => Issuer,
58-
oauth_metadata_url => OAuthProvider#oauth_provider.discovery_endpoint
59-
}
60-
end,
61-
case OAuthProvider#oauth_provider.end_session_endpoint of
62-
undefined -> Map0;
63-
V -> maps:put(end_session_endpoint, V, Map0)
64-
end.
61+
% only include issuer and end_session_endpoint for now.
62+
% The other endpoints are resolved by oidc-client library
63+
Map0 = case OAuthProvider#oauth_provider.issuer of
64+
undefined ->
65+
#{};
66+
Issuer ->
67+
#{
68+
oauth_provider_url => Issuer,
69+
oauth_metadata_url =>
70+
OAuthProvider#oauth_provider.discovery_endpoint
71+
}
72+
end,
73+
case OAuthProvider#oauth_provider.end_session_endpoint of
74+
undefined -> Map0;
75+
V -> maps:put(end_session_endpoint, V, Map0)
76+
end.
6577

66-
skip_unknown_mgt_resource_servers(MgtOauthResources, OAuth2Resources) ->
67-
maps:filter(fun(Key, _Value) -> maps:is_key(Key, OAuth2Resources) end, MgtOauthResources).
78+
skip_unknown_mgt_resource_servers(ManagementProps, OAuth2Resources) ->
79+
maps:filter(fun(Key, _Value) -> maps:is_key(Key, OAuth2Resources) end,
80+
proplists:get_value(oauth_resource_servers, ManagementProps, #{})).
6881
skip_disabled_mgt_resource_servers(MgtOauthResources) ->
69-
maps:filter(fun(_Key, Value) -> not proplists:get_value(disabled, Value, false) end, MgtOauthResources).
82+
maps:filter(fun(_Key, Value) ->
83+
not proplists:get_value(disabled, Value, false) end,
84+
MgtOauthResources).
7085

7186
extract_oauth2_and_mgt_resources(OAuth2BackendProps, ManagementProps) ->
72-
OAuth2Resources = getAllDeclaredOauth2Resources(OAuth2BackendProps),
73-
MgtResources0 = skip_unknown_mgt_resource_servers(proplists:get_value(oauth_resource_servers,
74-
ManagementProps, #{}), OAuth2Resources),
75-
MgtResources1 = maps:merge(MgtResources0, maps:filtermap(fun(K,_V) ->
76-
case maps:is_key(K, MgtResources0) of
77-
true -> false;
78-
false -> {true, [{id, K}]}
79-
end end, OAuth2Resources)),
80-
MgtResources = maps:map(
81-
fun(K,V) -> merge_oauth_provider_info(maps:get(K, OAuth2Resources, #{}), V, ManagementProps) end,
82-
skip_disabled_mgt_resource_servers(MgtResources1)),
83-
case maps:size(MgtResources) of
84-
0 -> {};
85-
_ -> {MgtResources}
86-
end.
87+
OAuth2Resources = getAllDeclaredOauth2Resources(OAuth2BackendProps),
88+
MgtResources0 = skip_unknown_mgt_resource_servers(ManagementProps,
89+
OAuth2Resources),
90+
MgtResources1 = maps:merge(maps:filtermap(fun(K,_V) ->
91+
case maps:is_key(K, MgtResources0) of
92+
true -> false;
93+
false -> {true, [{id, K}]}
94+
end end, OAuth2Resources), MgtResources0),
95+
MgtResources = maps:map(
96+
fun(K,V) -> merge_oauth_provider_info(
97+
maps:get(K, OAuth2Resources, #{}), V, ManagementProps) end,
98+
skip_disabled_mgt_resource_servers(MgtResources1)),
99+
case maps:size(MgtResources) of
100+
0 -> {};
101+
_ -> {MgtResources}
102+
end.
87103

88104
getAllDeclaredOauth2Resources(OAuth2BackendProps) ->
89-
OAuth2Resources = proplists:get_value(resource_servers, OAuth2BackendProps, #{}),
90-
case proplists:get_value(resource_server_id, OAuth2BackendProps) of
91-
undefined -> OAuth2Resources;
92-
Id -> maps:put(Id, buildRootResourceServerIfAny(Id, OAuth2BackendProps),
93-
OAuth2Resources)
94-
end.
105+
OAuth2Resources = proplists:get_value(resource_servers, OAuth2BackendProps,
106+
#{}),
107+
case proplists:get_value(resource_server_id, OAuth2BackendProps) of
108+
undefined ->
109+
OAuth2Resources;
110+
Id ->
111+
maps:put(Id, buildRootResourceServerIfAny(Id, OAuth2BackendProps),
112+
OAuth2Resources)
113+
end.
95114
buildRootResourceServerIfAny(Id, Props) ->
96-
[ {id, Id},
97-
{oauth_client_id,
98-
proplists:get_value(oauth_client_id, Props)},
99-
{oauth_client_secret,
100-
proplists:get_value(oauth_client_secret, Props)},
101-
{oauth_response_type,
102-
proplists:get_value(oauth_response_type, Props)},
103-
{oauth_authorization_endpoint_params,
104-
proplists:get_value(oauth_authorization_endpoint_params, Props)},
105-
{oauth_token_endpoint_params,
106-
proplists:get_value(oauth_token_endpoint_params, Props)}
107-
].
115+
[
116+
{id, Id},
117+
{oauth_provider_id, proplists:get_value(oauth_provider_id, Props)}
118+
].
108119

109120
authSettings() ->
110-
ManagementProps = application:get_all_env(rabbitmq_management),
111-
OAuth2BackendProps = application:get_all_env(rabbitmq_auth_backend_oauth2),
112-
EnableOAUTH = proplists:get_value(oauth_enabled, ManagementProps, false),
113-
case EnableOAUTH of
114-
false -> [{oauth_enabled, false}];
115-
true ->
116-
case extract_oauth2_and_mgt_resources(OAuth2BackendProps, ManagementProps) of
117-
{MgtResources} -> produce_auth_settings(MgtResources, ManagementProps);
118-
{} -> [{oauth_enabled, false}]
119-
end
121+
ManagementProps = application:get_all_env(rabbitmq_management),
122+
OAuth2BackendProps = application:get_all_env(rabbitmq_auth_backend_oauth2),
123+
EnableOAUTH = proplists:get_value(oauth_enabled, ManagementProps, false),
124+
case EnableOAUTH of
125+
false -> [{oauth_enabled, false}];
126+
true ->
127+
case extract_oauth2_and_mgt_resources(OAuth2BackendProps,
128+
ManagementProps) of
129+
{MgtResources} ->
130+
produce_auth_settings(MgtResources, ManagementProps);
131+
{} ->
132+
[{oauth_enabled, false}]
133+
end
120134
end.
121135

122-
skip_mgt_resource_servers_without_oauth_client_id_with_sp_initiated_logon(MgtResourceServers, ManagementProps) ->
123-
DefaultOauthInitiatedLogonType = proplists:get_value(oauth_initiated_logon_type, ManagementProps, sp_initiated),
124-
maps:filter(fun(_K,ResourceServer) ->
125-
SpInitiated = case maps:get(oauth_initiated_logon_type, ResourceServer, DefaultOauthInitiatedLogonType) of
126-
sp_initiated -> true;
127-
_ -> false
128-
end,
129-
not SpInitiated or
130-
not is_invalid([maps:get(oauth_client_id, ResourceServer, undefined)]) end, MgtResourceServers).
131-
132-
133-
filter_mgt_resource_servers_without_oauth_client_id_for_sp_initiated(MgtResourceServers, ManagementProps) ->
134-
case is_invalid([proplists:get_value(oauth_client_id, ManagementProps)]) of
135-
true -> skip_mgt_resource_servers_without_oauth_client_id_with_sp_initiated_logon(MgtResourceServers, ManagementProps);
136-
false -> MgtResourceServers
137-
end.
136+
% invalid -> those resources that dont have an oauth_client_id and
137+
% their login_type is sp_initiated
138+
skip_invalid_mgt_resource_servers(MgtResourceServers, ManagementProps) ->
139+
DefaultOauthInitiatedLogonType = proplists:get_value(
140+
oauth_initiated_logon_type, ManagementProps, sp_initiated),
141+
maps:filter(fun(_K,ResourceServer) ->
142+
SpInitiated =
143+
case maps:get(oauth_initiated_logon_type, ResourceServer,
144+
DefaultOauthInitiatedLogonType) of
145+
sp_initiated -> true;
146+
_ -> false
147+
end,
148+
not SpInitiated or not is_invalid([maps:get(oauth_client_id,
149+
ResourceServer, undefined)])
150+
end, MgtResourceServers).
151+
152+
% filter -> include only those resources with an oauth_client_id
153+
% or those whose logon type is not sp_initiated
154+
filter_out_invalid_mgt_resource_servers(MgtResourceServers, ManagementProps) ->
155+
case is_invalid([proplists:get_value(oauth_client_id, ManagementProps)]) of
156+
true ->
157+
skip_invalid_mgt_resource_servers(MgtResourceServers,
158+
ManagementProps);
159+
false ->
160+
MgtResourceServers
161+
end.
138162

139163
filter_mgt_resource_servers_without_oauth_provider_url(MgtResourceServers) ->
140-
maps:filter(fun(_K1,V1) -> maps:is_key(oauth_provider_url, V1) end, MgtResourceServers).
164+
maps:filter(fun(_K1,V1) -> maps:is_key(oauth_provider_url, V1) end,
165+
MgtResourceServers).
141166

142167
ensure_oauth_resource_server_properties_are_binaries(Key, Value) ->
143-
case Key of
144-
oauth_authorization_endpoint_params -> Value;
145-
oauth_token_endpoint_params -> Value;
146-
_ -> to_binary(Value)
147-
end.
168+
case Key of
169+
oauth_authorization_endpoint_params -> Value;
170+
oauth_token_endpoint_params -> Value;
171+
_ -> to_binary(Value)
172+
end.
148173

149174
produce_auth_settings(MgtResourceServers, ManagementProps) ->
150-
ConvertValuesToBinary = fun(_K,V) -> [
151-
{K1, ensure_oauth_resource_server_properties_are_binaries(K1, V1)} || {K1,V1}
152-
<- maps:to_list(V)] end,
153-
FilteredMgtResourceServers = filter_mgt_resource_servers_without_oauth_provider_url(
154-
filter_mgt_resource_servers_without_oauth_client_id_for_sp_initiated(MgtResourceServers, ManagementProps)),
155-
156-
case maps:size(FilteredMgtResourceServers) of
157-
0 -> [{oauth_enabled, false}];
158-
_ ->
159-
filter_empty_properties([
160-
{oauth_enabled, true},
161-
{oauth_resource_servers, maps:map(ConvertValuesToBinary, FilteredMgtResourceServers)},
162-
to_tuple(oauth_disable_basic_auth, ManagementProps, fun to_binary/1, true),
163-
to_tuple(oauth_client_id, ManagementProps),
164-
to_tuple(oauth_client_secret, ManagementProps),
165-
to_tuple(oauth_scopes, ManagementProps),
166-
case proplists:get_value(oauth_initiated_logon_type, ManagementProps, sp_initiated) of
167-
sp_initiated -> {};
168-
idp_initiated -> {oauth_initiated_logon_type, <<"idp_initiated">>}
169-
end,
170-
to_tuple(oauth_authorization_endpoint_params, ManagementProps, undefined, undefined),
171-
to_tuple(oauth_token_endpoint_params, ManagementProps, undefined, undefined)
172-
])
175+
ConvertValuesToBinary = fun(_K,V) ->
176+
[
177+
{K1, ensure_oauth_resource_server_properties_are_binaries(K1, V1)}
178+
|| {K1,V1} <- maps:to_list(V)
179+
] end,
180+
FilteredMgtResourceServers =
181+
filter_mgt_resource_servers_without_oauth_provider_url(
182+
filter_out_invalid_mgt_resource_servers(MgtResourceServers,
183+
ManagementProps)),
184+
185+
case maps:size(FilteredMgtResourceServers) of
186+
0 ->
187+
[{oauth_enabled, false}];
188+
_ ->
189+
filter_empty_properties([
190+
{oauth_enabled, true},
191+
{oauth_resource_servers,
192+
maps:map(ConvertValuesToBinary, FilteredMgtResourceServers)},
193+
to_tuple(oauth_disable_basic_auth, ManagementProps,
194+
fun to_binary/1, true),
195+
to_tuple(oauth_client_id, ManagementProps),
196+
to_tuple(oauth_client_secret, ManagementProps),
197+
to_tuple(oauth_scopes, ManagementProps),
198+
case proplists:get_value(oauth_initiated_logon_type,
199+
ManagementProps, sp_initiated) of
200+
sp_initiated ->
201+
{};
202+
idp_initiated ->
203+
{oauth_initiated_logon_type, <<"idp_initiated">>}
204+
end,
205+
to_tuple(oauth_authorization_endpoint_params, ManagementProps,
206+
undefined, undefined),
207+
to_tuple(oauth_token_endpoint_params, ManagementProps,
208+
undefined, undefined)
209+
])
173210
end.
174211

175212
filter_empty_properties(ListOfProperties) ->
176-
lists:filter(fun(Prop) ->
177-
case Prop of
178-
{} -> false;
179-
_ -> true
180-
end
181-
end, ListOfProperties).
213+
lists:filter(fun(Prop) ->
214+
case Prop of
215+
{} -> false;
216+
_ -> true
217+
end
218+
end, ListOfProperties).
182219

183220
to_binary(Value) when is_boolean(Value)-> Value;
184221
to_binary(Value) -> rabbit_data_coercion:to_binary(Value).

0 commit comments

Comments
 (0)