Closed papugamichal closed 3 years ago
How can we QA this?
I'd like to do some renaming of config keys and it would be great to support the current (UAA-specific) key names as aliases. I'd be happy to handle that.
rabbitmq.managementwebsite
is one name that we must change and our team potentially would not have control over this (unlike, say, the configuration keys). "Management website" is not a term any of our documentation uses. Moreover, the "website" part is redundant. I'm not sure where does this IdentityServer uses that scope name but it should probably be rabbitmq.management_ui
.
I'd prefer rabbitmq.management
(it would also match the name of the permission tag the UI uses) but that is not specific enough.
I will provide solution with IdentityServer for testing purposes.
What are benefits of keeping UAA naming? Are there - in other plugins - dependencies to it? That was a deliberate change, because I though with IdentityServer support I do not want to have in code properties names related to specific OAuth2 provider. I really want to know your point of view and pro and cons to keep UAA naming convention.
Update: thanks for your response. It's looks like we have posted in the same time.
rabbitmq.managementwebsite
is one name that we must change and our team potentially would not have control over this (unlike, say, the configuration keys).
I should point out that i tried to create code as flexible as possible, thus "rabbitmq.managementwebsite" it's only example. As "rabbitmq" equals to "resouce_server_id" parameter value, that "managementwebsite" can be any other value, but it has to mach value defined by "{role_picklock, <<"managementwebsite">>}" developed in https://github.com/rabbitmq/rabbitmq-auth-backend-oauth2/pull/39.
OK, I'm just making sure this value is not relied on elsewhere.
@michaelklishin ok, its reasonable to keep variable UAA naming convention because using uaa jwt to decode incoming token. I reverted original naming.
In separate repo I prepared dedicated solution with preconfigured IdentityServer4 for Rabbit Management. Its based on IdentityServer4.Demo solution which its quite simple but i wanted to keep it even simpler so removed unnecessarily parts and keep only configuration for Rabbit. README.md file contains manual how to setup and use it.
Below advanced.config file was preconfigured to working with IdentityServer:
[
{rabbit, [
{auth_backends, [rabbit_auth_backend_oauth2]},
{log, [
{file, [
{level, debug}
]}
]}
]},
{rabbitmq_management, [
{enable_uaa, true},
{uaa_client_id, "GitHub.RabbitMq.ManagementWebsite.Local"},
{uaa_location, "http://localhost:50000"},
{oauth2_scopes, "openid rabbitmq.managementwebsite"},
{oauth2_implementation, identityserver},
{tcp_config, [
{port, 15672},
{cowboy_opts, [{max_header_value_length, 10000}]}
]}
]},
{rabbitmq_auth_backend_oauth2, [
{resource_server_id, <<"rabbitmq">>},
{key_config, [
{signing_keys, #{
<<"OXNwd_TLdbIcOex6bLLStQ">> => {map, #{
<<"kty">> => <<"RSA">>,
<<"alg">> => <<"RS256">>,
<<"e">> => <<"AQAB">>,
<<"n">> => <<"sfq4sO8d2EPTxQqb56JTHNZ0OYr00qXfhxubmJUoiUTWjmTxtD48hTP2j-vgG4qw0eKeZyV8qZpA0q5w9HLk5xXNghwf5KMUDGiNhFd_5URBpVBcZ0fDSX2FwDTyRbF0XrxiYofROQeVOxbMIXHD0vCzTrzoypD6AA6wWI1ej4t-Zn5mpCG4DijIe-Ki0MJ4D58yY6YmuoERPhFNW1DmSKSohhex89anfrBfkIoyaBg9KNMtQW7oky5sPDH0GYqEWeXf4jqv4ODL-FtJhi74inUc2knXgznlkC15r-X_ubPv0ngvxetUELJFReWqyQDELwk_CBLZtxUiCkMZNl6JgQ">>
}}
}}
]},
{role_picklock, <<"managementwebsite">>},
{role_scope_map, #{
<<"RabbitManagement_Management">> => [<<"tag:management">>, <<"configure:*/*">>],
<<"RabbitManagement_Policymaker">> => [<<"tag:policymaker">>, <<"configure:*/*">>],
<<"RabbitManagement_Monitoring">> => [<<"tag:monitoring">>, <<"configure:*/*">>],
<<"RabbitManagement_Administrator">> => [<<"tag:administrator">>, <<"configure:*/*">>, <<"write:*/*">>, <<"read:*/*">>]}
}
]}
].
Before first use, please check values of "signing_key_id" (in my example: OXNwd_TLdbIcOex6bLLStQ), and "n" with "kid" and "n" values returned by http://localhost:50000/.well-known/openid-configuration/jwks endpoint.
In this example i keep set "debug" logging level, because sometimes its can provice some useful information.
Last thing to QA this PR, you have to build rabbitmq_auth_backend_oauth2 plugin for ManagementUI to be able to decode incomming tokens.
Please, let me know if you have any troubles with IdentityServer. Is if sufficient to QA this PR?
@michaelklishin Michael, any update? How can I help with handling this PR?
There doesn't see to be any progress on this PR => closing.
@michaelklishin thank you for your support so far. I have been planning to get back and finish this feature in next couple of days. Please, be in touch :)
@papugamichal OK, fair enough
I do not understand why we need to bundle a regular, minimized and two "slim" versions of oidc-client at the same time.
Good point. Cleaned up.
I'd really like to see the IdentityServer-specific /callback to be named accordingly.
OK. I think that /silent.html also should be renamed to be more precise about it existence purpose.
My proposition to rename: /callback.html to /afterSignInCallback.html or /afterSignInRecall.html /silent.html to /silenTokenRenewCallback.html or /silenTokenRenewRecall.html
What do you think?
I'd use /postSigninCallback.html
and /silentTokenRenewal.html
.
@michaelklishin Michael, do you see what else should be done around this implementation? Edit: by miss click I closed this PR... sorry, reopen.
@michaelklishin i would like to ask you to review this PR once again. Do you have any other remarks?
FWIW this has not been forgotten.
Proposed Changes
Please consider to add support for scenarios where Rabbit Management backend handle both UAA and IdentityServer4 (IS4) OAuth2 token providers.
Proposed solution uses OIDC (OpenId-Connect library) client to connect both Rabbit Management UI javascript backend and IdentityServer. In this case OIDC was configured to handle signin/signout redirections, store and management of returned JWT token in browser memory and automatically handle to refresh token when it's about to expire soon.
First attempt to integrate Management UI with IdentityServer assumed to obligatory use modified rabbitmq-auth-backend-oauth2 pluggin but now it is optional. I will provide manual for both scenarios. This implementation add few more options to _rabbitmqmanagement secrion, but with respect to UAA implementation there are shared parameters for both providers.
Below example config has arrows for new parameters used in IS4 case:
_oauth2scopes parameter was configured as string _oauth2implementation parameter was configured as enum [uaa , identityserver] with defeault uaa value when its not configured
Options like: _enableoauth2, _uaa_clientid and _uaalocation are shared by UAA and IdentityServer implementations. Their meainng in both cases are the same.
Why do I need _oauth2scopes parameter? Analyzed UAA implementation shows that Singular in rpFrame.js has hard coded "openid" scope with whom is requesting to UAA server. I have considered to make Singular use _oauth2scopes as well, but I am not entirely sure about Singular origin, why he's code looks like obfuscated in Rabbit repo and any other but potentailly consequences regardled to UAA.
I found that when IdentityServer is requested without any scope assigned to IS4's ApiResource (ApiResource = resource_server_id) it returns token where aud (audience) section hasn't have included information about configured _resource_serverid - in another words it has no information that this token is valid for configured _resource_serverid.
eyJhbGciOiJSUzI1NiIsImtpZCI6Ik9YTndkX1RMZGJJY09leDZiTExTdFEiLCJ0eXAiOiJKV1QifQ.eyJuYmYiOjE1NzU4MTE4NDIsImV4cCI6MTYwNzM2ODc2OCwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAwMCIsImF1ZCI6IkdpdEh1Yi5SYWJiaXRNcS5NYW5hZ2VtZW50V2Vic2l0ZS5Mb2NhbCIsIm5vbmNlIjoiZmI1NWFjODRjYzEzNDMxZDg5YTFiMGY0YTAyNTE4NTQiLCJpYXQiOjE1NzU4MTE4NDIsImF0X2hhc2giOiJnYnY3RVB4WGJ4d0Q1bU9lVFAtLVFRIiwic19oYXNoIjoiV2dtb05aT3VoUWNsQWJNaW10YlllUSIsInNpZCI6IlBHVnNCM2lDTnFlTkhuYlJ2RGVKb0EiLCJzdWIiOiIxMTEiLCJhdXRoX3RpbWUiOjE1NzU4MTE4MDUsImlkcCI6ImxvY2FsIiwiYW1yIjpbInB3ZCJdfQ.pYBEUUe3ViAY-LDVwB5QP1fW0VFuxH017i16zvLjjDaZKJZVFLxu0EEc0SeNUD-kaifPPzB9d0KlCspptewsoGpFRbPfCFrTUOVl2G18QvW2ENUKMIxtGB_rMQLfeAEn9lYARwr1-W4i-ej_ZC2M00BlfUXiPyEYDGDRziE2z3kYmHODDlhZcrmLsu_BF0GQcaQzUj4HA9-ntw5OwkM9F1md9OhYtAzjIjTqIgkX8h9cw7u_cp_wAIlaQikxNeDQP3KO-IrwW39bkX6z0i3uk8oLOOC9h3bcd01BLMnzfor_UlN8VCZkEDTXF2S_0ywbliNq76w_t2Nnzju_B-Z2Rw
When such token is provided authorization backend responses (to log) with message:
How to tests it? I prepared dedicated solution with preconfigured IdentityServer4. README.md file contains manual how to setup and use it.
Case where we do need use any ComplexClaims: (please note that any user will have the same perrmision set)
advanced.config
Case where we use ComplexClaims: (please note that each user may have his own permisions set included in _extra_scopessource JWT section)
advanced.config
Types of Changes
What types of changes does your code introduce to this project?
Checklist
Put an
x
in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask on the mailing list. We're here to help! This is simply a reminder of what we are going to look for before merging your code.CONTRIBUTING.md
document