Merge pull request #8412 from rabbitmq/fix-8391
Make scopes optional for oauth2 authentication
This commit is contained in:
commit
bcc2bc8525
|
@ -496,7 +496,7 @@ post_process_payload_in_rich_auth_request_format(#{<<"authorization_details">> :
|
|||
|
||||
|
||||
|
||||
validate_payload(#{?SCOPE_JWT_FIELD := _Scope } = DecodedToken) ->
|
||||
validate_payload(DecodedToken) ->
|
||||
ResourceServerEnv = application:get_env(?APP, ?RESOURCE_SERVER_ID, <<>>),
|
||||
ResourceServerId = rabbit_data_coercion:to_binary(ResourceServerEnv),
|
||||
ScopePrefix = application:get_env(?APP, ?SCOPE_PREFIX, <<ResourceServerId/binary, ".">>),
|
||||
|
@ -507,6 +507,11 @@ validate_payload(#{?SCOPE_JWT_FIELD := Scope, ?AUD_JWT_FIELD := Aud} = DecodedTo
|
|||
ok -> {ok, DecodedToken#{?SCOPE_JWT_FIELD => filter_scopes(Scope, ScopePrefix)}};
|
||||
{error, Err} -> {refused, {invalid_aud, Err}}
|
||||
end;
|
||||
validate_payload(#{?AUD_JWT_FIELD := Aud} = DecodedToken, ResourceServerId, _ScopePrefix) ->
|
||||
case check_aud(Aud, ResourceServerId) of
|
||||
ok -> {ok, DecodedToken};
|
||||
{error, Err} -> {refused, {invalid_aud, Err}}
|
||||
end;
|
||||
validate_payload(#{?SCOPE_JWT_FIELD := Scope} = DecodedToken, _ResourceServerId, ScopePrefix) ->
|
||||
case application:get_env(?APP, ?VERIFY_AUD, true) of
|
||||
true -> {error, {badarg, {aud_field_is_missing}}};
|
||||
|
@ -534,7 +539,8 @@ check_aud(Aud, ResourceServerId) ->
|
|||
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
get_scopes(#{?SCOPE_JWT_FIELD := Scope}) -> Scope.
|
||||
get_scopes(#{?SCOPE_JWT_FIELD := Scope}) -> Scope;
|
||||
get_scopes(#{}) -> [].
|
||||
|
||||
-spec get_expanded_scopes(map(), #resource{}) -> [binary()].
|
||||
get_expanded_scopes(Token, #resource{virtual_host = VHost}) ->
|
||||
|
|
|
@ -84,6 +84,15 @@ token_with_scopes_and_expiration(Scopes, Expiration) ->
|
|||
<<"aud">> => [<<"rabbitmq">>],
|
||||
<<"scope">> => Scopes}.
|
||||
|
||||
token_without_scopes() ->
|
||||
%% expiration is a timestamp with precision in seconds
|
||||
#{
|
||||
<<"kid">> => <<"token-key">>,
|
||||
<<"iss">> => <<"unit_test">>,
|
||||
<<"foo">> => <<"bar">>,
|
||||
<<"aud">> => [<<"rabbitmq">>]
|
||||
}.
|
||||
|
||||
fixture_token() ->
|
||||
fixture_token([]).
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ all() ->
|
|||
permission_resource,
|
||||
permission_topic
|
||||
].
|
||||
|
||||
|
||||
variable_expansion(_Config) ->
|
||||
Scenarios = [
|
||||
{ "Emtpy Scopes",
|
||||
|
|
|
@ -19,8 +19,12 @@ all() ->
|
|||
test_validate_payload_resource_server_id_mismatch,
|
||||
test_validate_payload_with_scope_prefix,
|
||||
test_validate_payload,
|
||||
test_validate_payload_without_scope,
|
||||
test_validate_payload_when_verify_aud_false,
|
||||
test_successful_access_with_a_token,
|
||||
test_successful_authentication_without_scopes,
|
||||
test_successful_authorization_without_scopes,
|
||||
test_unsuccessful_access_without_scopes,
|
||||
test_successful_access_with_a_token_with_variables_in_scopes,
|
||||
test_successful_access_with_a_parsed_token,
|
||||
test_successful_access_with_a_token_that_has_tag_scopes,
|
||||
|
@ -609,6 +613,30 @@ post_process_payload_with_complex_claim_authorization(Authorization) ->
|
|||
{true, Payload} = uaa_jwt_jwt:decode_and_verify(Jwk, EncodedToken),
|
||||
rabbit_auth_backend_oauth2:post_process_payload(Payload).
|
||||
|
||||
test_successful_authentication_without_scopes(_) ->
|
||||
Jwk = ?UTIL_MOD:fixture_jwk(),
|
||||
UaaEnv = [{signing_keys, #{<<"token-key">> => {map, Jwk}}}],
|
||||
application:set_env(rabbitmq_auth_backend_oauth2, key_config, UaaEnv),
|
||||
application:set_env(rabbitmq_auth_backend_oauth2, resource_server_id, <<"rabbitmq">>),
|
||||
|
||||
Username = <<"username">>,
|
||||
Token = ?UTIL_MOD:sign_token_hs(?UTIL_MOD:token_with_sub(?UTIL_MOD:fixture_token(), Username), Jwk),
|
||||
|
||||
{ok, #auth_user{username = Username} } =
|
||||
rabbit_auth_backend_oauth2:user_login_authentication(Username, [{password, Token}]).
|
||||
|
||||
test_successful_authorization_without_scopes(_) ->
|
||||
Jwk = ?UTIL_MOD:fixture_jwk(),
|
||||
UaaEnv = [{signing_keys, #{<<"token-key">> => {map, Jwk}}}],
|
||||
application:set_env(rabbitmq_auth_backend_oauth2, key_config, UaaEnv),
|
||||
application:set_env(rabbitmq_auth_backend_oauth2, resource_server_id, <<"rabbitmq">>),
|
||||
|
||||
Username = <<"username">>,
|
||||
Token = ?UTIL_MOD:sign_token_hs(?UTIL_MOD:token_with_sub(?UTIL_MOD:fixture_token(), Username), Jwk),
|
||||
|
||||
{ok, _ } =
|
||||
rabbit_auth_backend_oauth2:user_login_authorization(Username, [{password, Token}]).
|
||||
|
||||
test_successful_access_with_a_token(_) ->
|
||||
%% Generate a token with JOSE
|
||||
%% Check authorization with the token
|
||||
|
@ -980,6 +1008,21 @@ test_unsuccessful_access_with_a_bogus_token(_) ->
|
|||
?assertMatch({refused, _, _},
|
||||
rabbit_auth_backend_oauth2:user_login_authentication(Username, [{password, <<"not a token">>}])).
|
||||
|
||||
test_unsuccessful_access_without_scopes(_) ->
|
||||
Username = <<"username">>,
|
||||
application:set_env(rabbitmq_auth_backend_oauth2, resource_server_id, <<"rabbitmq">>),
|
||||
|
||||
Jwk = ?UTIL_MOD:fixture_jwk(),
|
||||
Token = ?UTIL_MOD:sign_token_hs(?UTIL_MOD:token_with_sub(?UTIL_MOD:token_without_scopes(), Username), Jwk),
|
||||
UaaEnv = [{signing_keys, #{<<"token-key">> => {map, Jwk}}}],
|
||||
application:set_env(rabbitmq_auth_backend_oauth2, key_config, UaaEnv),
|
||||
|
||||
{ok, #auth_user{username = Username, tags = [], impl = CredentialsFun } = AuthUser} =
|
||||
rabbit_auth_backend_oauth2:user_login_authentication(Username, [{password, Token}]),
|
||||
|
||||
ct:log("authuser ~p ~p ", [AuthUser, CredentialsFun()]),
|
||||
assert_vhost_access_denied(AuthUser, <<"vhost">>).
|
||||
|
||||
test_restricted_vhost_access_with_a_valid_token(_) ->
|
||||
Username = <<"username">>,
|
||||
application:set_env(rabbitmq_auth_backend_oauth2, resource_server_id, <<"rabbitmq">>),
|
||||
|
@ -1277,6 +1320,12 @@ test_validate_payload(_) ->
|
|||
<<"scope">> => [<<"bar">>, <<"other.third">>]}},
|
||||
rabbit_auth_backend_oauth2:validate_payload(KnownResourceServerId, ?RESOURCE_SERVER_ID, ?DEFAULT_SCOPE_PREFIX)).
|
||||
|
||||
test_validate_payload_without_scope(_) ->
|
||||
KnownResourceServerId = #{<<"aud">> => [?RESOURCE_SERVER_ID]
|
||||
},
|
||||
?assertEqual({ok, #{<<"aud">> => [?RESOURCE_SERVER_ID] }},
|
||||
rabbit_auth_backend_oauth2:validate_payload(KnownResourceServerId, ?RESOURCE_SERVER_ID, ?DEFAULT_SCOPE_PREFIX)).
|
||||
|
||||
test_validate_payload_when_verify_aud_false(_) ->
|
||||
WithoutAud = #{
|
||||
<<"scope">> => [<<"foo">>, <<"rabbitmq.bar">>,
|
||||
|
|
Loading…
Reference in New Issue