summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcial Rosales <mrosales@pivotal.io>2023-01-30 15:54:11 +0100
committerMarcial Rosales <mrosales@pivotal.io>2023-01-31 11:45:59 +0100
commit9339ad1114ff90e1268911e57768783eb47889e6 (patch)
treee7bbb6ce2dad5a130e814e23b32d39eb8fe10f47
parent51e27f8a3fd3a7a14b884fb5e4eee36053aa9972 (diff)
downloadrabbitmq-server-git-9339ad1114ff90e1268911e57768783eb47889e6.tar.gz
Comment why we are propagating authz_backends
when opening an internal amqp connection
-rw-r--r--deps/rabbit/src/rabbit_direct.erl11
-rw-r--r--deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_session_sup.erl12
-rw-r--r--deps/rabbitmq_auth_backend_oauth2/src/rabbit_auth_backend_oauth2.erl7
3 files changed, 30 insertions, 0 deletions
diff --git a/deps/rabbit/src/rabbit_direct.erl b/deps/rabbit/src/rabbit_direct.erl
index b187d60f89..c2d88e5526 100644
--- a/deps/rabbit/src/rabbit_direct.erl
+++ b/deps/rabbit/src/rabbit_direct.erl
@@ -72,6 +72,16 @@ auth_fun({Username, Password}, VHost, ExtraAuthProps) ->
'broker_not_found_on_node' |
{'auth_failure', string()} | 'access_refused').
+%% Infos is a PropList which contains the content of the Proplist #amqp_adapter_info.additional_info
+%% among other credentials such as protocol, ssl information, etc.
+%% #amqp_adapter_info.additional_info may carry a credential called `authz_bakends` which has the
+%% content of the #user.authz_backends attribute. This means that we are propagating the outcome
+%% from the first successful authentication for the current user when opening an internal
+%% amqp connection. This is particularly relevant for protocol plugins such as AMQP 1.0 where
+%% users are authenticated in one context and later on an internal amqp connection is opened
+%% on a different context. In other words, we do not have anymore the initial credentials presented
+%% during the first authentication. However, we do have the outcome from such successful authentication.
+
connect(Creds, VHost, Protocol, Pid, Infos) ->
ExtraAuthProps = append_authz_backends(extract_extra_auth_props(Creds, VHost, Pid, Infos), Infos),
@@ -115,6 +125,7 @@ extract_extra_auth_props(Creds, VHost, Pid, Infos) ->
maybe_call_connection_info_module(Protocol, Creds, VHost, Pid, Infos)
end.
+
append_authz_backends(AuthProps, Infos) ->
case proplists:get_value(authz_backends, Infos, undefined) of
undefined -> AuthProps;
diff --git a/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_session_sup.erl b/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_session_sup.erl
index a530213d50..5e08fd9bc9 100644
--- a/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_session_sup.erl
+++ b/deps/rabbitmq_amqp1_0/src/rabbit_amqp1_0_session_sup.erl
@@ -86,6 +86,18 @@ init([]) ->
auto_shutdown => any_significant},
{ok, {SupFlags, []}}.
+
+%% For each AMQP 1.0 session opened, an internal AMQP connection is opened too.
+%% This AMQP connection will authenticate the user again. Again because at this point
+%% the SASL handshake has already taken place and this user has already been authenticated.
+%% However, we do not have the credentials the user presented. For that reason, the
+%% #amqp_adapter_info.additional_info carriess an extra property called authz_backends
+%% which is initialized from the #user.authz_backends attribute. In other words, we
+%% propagate the outcome from the first authentication attempt to the subsequent attempts.
+
+%% Note: Check out rabbit_direct.erl to see how `authz_bakends` is propagated from
+% amqp_adapter_info.additional_info to the rabbit_access_control module
+
adapter_info(User, Sock) ->
AdapterInfo = amqp_connection:socket_adapter_info(Sock, {'AMQP', "1.0"}),
AdapterInfo#amqp_adapter_info{additional_info =
diff --git a/deps/rabbitmq_auth_backend_oauth2/src/rabbit_auth_backend_oauth2.erl b/deps/rabbitmq_auth_backend_oauth2/src/rabbit_auth_backend_oauth2.erl
index 7f33a61207..47912f029b 100644
--- a/deps/rabbitmq_auth_backend_oauth2/src/rabbit_auth_backend_oauth2.erl
+++ b/deps/rabbitmq_auth_backend_oauth2/src/rabbit_auth_backend_oauth2.erl
@@ -536,6 +536,13 @@ check_aud(Aud, ResourceServerId) ->
get_scopes(#{?SCOPE_JWT_FIELD := Scope}) -> Scope.
+%% A token may be present in the password credential or in the rabbit_auth_backend_oauth2
+%% credential. The former is the most common scenario for the first time authentication.
+%% However, there are scenarios where the same user (on the same connection) is authenticated
+%% more than once. When this scenario occurs, we extract the token from the credential
+%% called rabbit_auth_backend_oauth2 whose value is the Decoded token returned during the
+%% first authentication.
+
-spec token_from_context(map()) -> binary() | undefined.
token_from_context(AuthProps) ->
case maps:get(password, AuthProps, undefined) of