Add var expansion to vhost and resource access

This commit is contained in:
Marcial Rosales 2025-05-28 16:13:43 +02:00
parent b09e2f2dad
commit 0023ba2a01
4 changed files with 55 additions and 20 deletions

View File

@ -87,11 +87,8 @@ user_login_authorization(Username, AuthProps) ->
check_vhost_access(#auth_user{impl = DecodedTokenFun}, check_vhost_access(#auth_user{impl = DecodedTokenFun},
VHost, _AuthzData) -> VHost, _AuthzData) ->
with_decoded_token(DecodedTokenFun(), with_decoded_token(DecodedTokenFun(),
fun(_Token) -> fun(Token) ->
DecodedToken = DecodedTokenFun(), Scopes = get_expanded_scopes(Token, #resource{virtual_host = VHost}),
Scopes = get_scope(DecodedToken),
ScopeString = rabbit_oauth2_scope:concat_scopes(Scopes, ","),
rabbit_log:debug("Matching virtual host '~ts' against the following scopes: ~ts", [VHost, ScopeString]),
rabbit_oauth2_scope:vhost_access(VHost, Scopes) rabbit_oauth2_scope:vhost_access(VHost, Scopes)
end). end).
@ -99,7 +96,7 @@ check_resource_access(#auth_user{impl = DecodedTokenFun},
Resource, Permission, _AuthzContext) -> Resource, Permission, _AuthzContext) ->
with_decoded_token(DecodedTokenFun(), with_decoded_token(DecodedTokenFun(),
fun(Token) -> fun(Token) ->
Scopes = get_scope(Token), Scopes = get_expanded_scopes(Token, Resource),
rabbit_oauth2_scope:resource_access(Resource, Permission, Scopes) rabbit_oauth2_scope:resource_access(Resource, Permission, Scopes)
end). end).

View File

@ -41,6 +41,7 @@ resource_access(#resource{virtual_host = VHost, name = Name},
end, end,
get_scope_permissions(Scopes)). get_scope_permissions(Scopes)).
-spec topic_access(rabbit_types:r(atom()), permission(), map(), [binary()]) -> boolean().
topic_access(#resource{virtual_host = VHost, name = ExchangeName}, topic_access(#resource{virtual_host = VHost, name = ExchangeName},
Permission, Permission,
#{routing_key := RoutingKey}, #{routing_key := RoutingKey},

View File

@ -117,6 +117,8 @@ fixture_token() ->
token_with_sub(TokenFixture, Sub) -> token_with_sub(TokenFixture, Sub) ->
maps:put(<<"sub">>, Sub, TokenFixture). maps:put(<<"sub">>, Sub, TokenFixture).
token_with_claim(TokenFixture, Name, Value) ->
maps:put(Name, Value, TokenFixture).
token_with_scopes(TokenFixture, Scopes) -> token_with_scopes(TokenFixture, Scopes) ->
maps:put(<<"scope">>, Scopes, TokenFixture). maps:put(<<"scope">>, Scopes, TokenFixture).

View File

@ -49,7 +49,8 @@ all() ->
test_unsuccessful_access_with_a_token_that_uses_missing_scope_alias_in_scope_field, test_unsuccessful_access_with_a_token_that_uses_missing_scope_alias_in_scope_field,
test_unsuccessful_access_with_a_token_that_uses_missing_scope_alias_in_extra_scope_source_field, test_unsuccessful_access_with_a_token_that_uses_missing_scope_alias_in_extra_scope_source_field,
test_username_from, test_username_from,
{group, with_rabbitmq_node} {group, with_rabbitmq_node},
{group, with_resource_server_id}
]. ].
groups() -> groups() ->
@ -62,11 +63,11 @@ groups() ->
}, },
{with_resource_server_id, [], [ {with_resource_server_id, [], [
test_successful_access_with_a_token, test_successful_access_with_a_token,
test_validate_payload_resource_server_id_mismatch,
test_successful_access_with_a_token_that_uses_single_scope_alias_in_scope_field, test_successful_access_with_a_token_that_uses_single_scope_alias_in_scope_field,
test_successful_access_with_a_token_that_uses_multiple_scope_aliases_in_scope_field, test_successful_access_with_a_token_that_uses_multiple_scope_aliases_in_scope_field,
test_successful_authorization_without_scopes, test_successful_authorization_without_scopes,
test_successful_authentication_without_scopes, test_successful_authentication_without_scopes,
test_successful_access_with_a_token_that_uses_single_scope_alias_with_var_expansion,
test_successful_access_with_a_token_that_uses_single_scope_alias_in_extra_scope_source_field, test_successful_access_with_a_token_that_uses_single_scope_alias_in_extra_scope_source_field,
test_successful_access_with_a_token_that_uses_multiple_scope_aliases_in_extra_scope_source_field, test_successful_access_with_a_token_that_uses_multiple_scope_aliases_in_extra_scope_source_field,
normalize_token_scope_with_additional_scopes_complex_claims, normalize_token_scope_with_additional_scopes_complex_claims,
@ -634,7 +635,7 @@ normalize_token_scope_with_additional_scopes_complex_claims(_) ->
<<"rabbitmq3">> => <<"rabbitmq3">> =>
[<<"rabbitmq-resource.write:*/*">>, [<<"rabbitmq-resource.write:*/*">>,
<<"rabbitmq-resource-write">>]}, <<"rabbitmq-resource-write">>]},
[<<"read:*/*">>, <<"rabbitmq.rabbitmq-resource-read">>] [<<"read:*/*">>]
}, },
{ {
"claims are map with list content - empty result", "claims are map with list content - empty result",
@ -647,7 +648,7 @@ normalize_token_scope_with_additional_scopes_complex_claims(_) ->
"claims are map with binary content", "claims are map with binary content",
#{ <<"rabbitmq">> => <<"rabbitmq-resource.read:*/* rabbitmq-resource-read">>, #{ <<"rabbitmq">> => <<"rabbitmq-resource.read:*/* rabbitmq-resource-read">>,
<<"rabbitmq3">> => <<"rabbitmq-resource.write:*/* rabbitmq-resource-write">>}, <<"rabbitmq3">> => <<"rabbitmq-resource.write:*/* rabbitmq-resource-write">>},
[<<"rabbitmq.rabbitmq-resource.read:*/*">>, <<"rabbitmq.rabbitmq-resource-read">>] [<<"read:*/*">>]
}, },
{ {
"claims are map with binary content - empty result", "claims are map with binary content - empty result",
@ -777,6 +778,45 @@ test_successful_access_with_a_token_that_has_tag_scopes(_) ->
{ok, #auth_user{username = Username, tags = [management, policymaker]}} = {ok, #auth_user{username = Username, tags = [management, policymaker]}} =
user_login_authentication(Username, [{password, Token}]). user_login_authentication(Username, [{password, Token}]).
test_successful_access_with_a_token_that_uses_single_scope_alias_with_var_expansion(_) ->
Jwk = ?UTIL_MOD:fixture_jwk(),
UaaEnv = [{signing_keys, #{<<"token-key">> => {map, Jwk}}}],
set_env(key_config, UaaEnv),
Alias = <<"client-alias-1">>,
set_env(scope_aliases, #{
Alias => [
<<"rabbitmq.configure:{vhost}/q-{sub}/rk-{client_id}**">>
]
}),
VHost = <<"vhost">>,
Username = <<"bob">>,
ClientId = <<"rmq">>,
Token = ?UTIL_MOD:sign_token_hs(?UTIL_MOD:token_with_sub(
?UTIL_MOD:token_with_claim(
?UTIL_MOD:token_with_scope_alias_in_scope_field(Alias), <<"client_id">>, ClientId),
Username), Jwk),
{ok, #auth_user{username = Username} = AuthUser} =
user_login_authentication(Username, [{password, Token}]),
%% vhost access
assert_vhost_access_granted(AuthUser, ClientId),
%% resource access
assert_resource_access_denied(AuthUser, VHost, <<"none">>, read),
assert_resource_access_granted(AuthUser, VHost, <<"q-bob">>, configure),
%% topic access
assert_topic_access_refused(AuthUser, VHost, <<"q-bob">>, configure,
#{routing_key => <<"rk-r2mq/#">>}),
assert_topic_access_granted(AuthUser, VHost, <<"q-bob">>, configure,
#{routing_key => <<"rk-rmq/#">>}),
application:unset_env(rabbitmq_auth_backend_oauth2, scope_aliases),
application:unset_env(rabbitmq_auth_backend_oauth2, key_config).
test_successful_access_with_a_token_that_uses_single_scope_alias_in_scope_field(_) -> test_successful_access_with_a_token_that_uses_single_scope_alias_in_scope_field(_) ->
Jwk = ?UTIL_MOD:fixture_jwk(), Jwk = ?UTIL_MOD:fixture_jwk(),
UaaEnv = [{signing_keys, #{<<"token-key">> => {map, Jwk}}}], UaaEnv = [{signing_keys, #{<<"token-key">> => {map, Jwk}}}],
@ -813,8 +853,7 @@ test_successful_access_with_a_token_that_uses_single_scope_alias_in_scope_field(
assert_resource_access_denied(AuthUser, VHost, <<"three">>, write), assert_resource_access_denied(AuthUser, VHost, <<"three">>, write),
application:unset_env(rabbitmq_auth_backend_oauth2, scope_aliases), application:unset_env(rabbitmq_auth_backend_oauth2, scope_aliases),
application:unset_env(rabbitmq_auth_backend_oauth2, key_config), application:unset_env(rabbitmq_auth_backend_oauth2, key_config).
application:unset_env(rabbitmq_auth_backend_oauth2, resource_server_id).
test_successful_access_with_a_token_that_uses_single_scope_alias_in_scope_field_and_custom_scope_prefix(_) -> test_successful_access_with_a_token_that_uses_single_scope_alias_in_scope_field_and_custom_scope_prefix(_) ->
@ -855,8 +894,7 @@ test_successful_access_with_a_token_that_uses_single_scope_alias_in_scope_field_
application:unset_env(rabbitmq_auth_backend_oauth2, scope_aliases), application:unset_env(rabbitmq_auth_backend_oauth2, scope_aliases),
application:unset_env(rabbitmq_auth_backend_oauth2, key_config), application:unset_env(rabbitmq_auth_backend_oauth2, key_config),
application:unset_env(rabbitmq_auth_backend_oauth2, scope_prefix), application:unset_env(rabbitmq_auth_backend_oauth2, scope_prefix).
application:unset_env(rabbitmq_auth_backend_oauth2, resource_server_id).
test_successful_access_with_a_token_that_uses_multiple_scope_aliases_in_scope_field(_) -> test_successful_access_with_a_token_that_uses_multiple_scope_aliases_in_scope_field(_) ->
Jwk = ?UTIL_MOD:fixture_jwk(), Jwk = ?UTIL_MOD:fixture_jwk(),
@ -901,8 +939,7 @@ test_successful_access_with_a_token_that_uses_multiple_scope_aliases_in_scope_fi
assert_resource_access_denied(AuthUser, VHost, <<"three">>, write), assert_resource_access_denied(AuthUser, VHost, <<"three">>, write),
application:unset_env(rabbitmq_auth_backend_oauth2, scope_aliases), application:unset_env(rabbitmq_auth_backend_oauth2, scope_aliases),
application:unset_env(rabbitmq_auth_backend_oauth2, key_config), application:unset_env(rabbitmq_auth_backend_oauth2, key_config).
application:unset_env(rabbitmq_auth_backend_oauth2, resource_server_id).
test_unsuccessful_access_with_a_token_that_uses_missing_scope_alias_in_scope_field(_) -> test_unsuccessful_access_with_a_token_that_uses_missing_scope_alias_in_scope_field(_) ->
Jwk = ?UTIL_MOD:fixture_jwk(), Jwk = ?UTIL_MOD:fixture_jwk(),
@ -976,8 +1013,7 @@ test_successful_access_with_a_token_that_uses_single_scope_alias_in_extra_scope_
assert_resource_access_denied(AuthUser, VHost, <<"three">>, write), assert_resource_access_denied(AuthUser, VHost, <<"three">>, write),
application:unset_env(rabbitmq_auth_backend_oauth2, scope_aliases), application:unset_env(rabbitmq_auth_backend_oauth2, scope_aliases),
application:unset_env(rabbitmq_auth_backend_oauth2, key_config), application:unset_env(rabbitmq_auth_backend_oauth2, key_config).
application:unset_env(rabbitmq_auth_backend_oauth2, resource_server_id).
test_successful_access_with_a_token_that_uses_multiple_scope_aliases_in_extra_scope_source_field(_) -> test_successful_access_with_a_token_that_uses_multiple_scope_aliases_in_extra_scope_source_field(_) ->
Jwk = ?UTIL_MOD:fixture_jwk(), Jwk = ?UTIL_MOD:fixture_jwk(),
@ -1021,8 +1057,7 @@ test_successful_access_with_a_token_that_uses_multiple_scope_aliases_in_extra_sc
assert_resource_access_denied(AuthUser, VHost, <<"three">>, write), assert_resource_access_denied(AuthUser, VHost, <<"three">>, write),
application:unset_env(rabbitmq_auth_backend_oauth2, scope_aliases), application:unset_env(rabbitmq_auth_backend_oauth2, scope_aliases),
application:unset_env(rabbitmq_auth_backend_oauth2, key_config), application:unset_env(rabbitmq_auth_backend_oauth2, key_config).
application:unset_env(rabbitmq_auth_backend_oauth2, resource_server_id).
test_unsuccessful_access_with_a_token_that_uses_missing_scope_alias_in_extra_scope_source_field(_) -> test_unsuccessful_access_with_a_token_that_uses_missing_scope_alias_in_extra_scope_source_field(_) ->
Jwk = ?UTIL_MOD:fixture_jwk(), Jwk = ?UTIL_MOD:fixture_jwk(),