Skip to content

Support for more general OAuth2 providers #2605

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
MirahImage opened this issue Nov 6, 2020 · 15 comments
Closed

Support for more general OAuth2 providers #2605

MirahImage opened this issue Nov 6, 2020 · 15 comments

Comments

@MirahImage
Copy link
Member

When using the rabbitmq-management plugin with the rabbitmq-auth-backen-oauth2, users are redirected to the OAuth server to authenticate following an implicit_grant flow. The plugin makes several assumptions about the structure of the endpoints provided by the OAuth server, not all of which are valid.

  1. The authentication endpoint is assumed to be at the location uaa_location/oauth/authorize. While the use of /authorize is general as specified in RFC 6749, the prefix of /oauth is specific to UAA.
  2. The /info endpoint is not general. RFC 8414 specifies that a generic OAuth2 server should provide the /.well-known/oauth-authorization-server endpoint for such purposes, but also that specific implementations may specify a different endpoint. For example, servers implementing OIDC may instead provide the /.well-known/openid-configuration endpoint.

In regards to the first point above, one solution would be to generalize the uaa_location advanced config to an oauth_location config property. In the specific case of UAA, the oauth_location would correspond to uaa_location/oauth.

Similarly, for the second point, we could provide an optional configuration for the metadata endpoint, with the default value being /.well-known/oauth-authorization-server.

@dcorbacho dcorbacho transferred this issue from rabbitmq/rabbitmq-management Nov 17, 2020
@MirahImage
Copy link
Member Author

MirahImage commented Mar 18, 2022

We are working on the support-general-oauth branch. We are currently adding test coverage for the login process.

Next steps:

  • Set up system for running a fake rabbitmq endpoint that returns the appropriate json
  • Run JSDOM.fromFile and check that it hits the rabbitmq endpoint to get the appropriately configured json
  • Write lots of tests
  • Red/Green/Refactor
  • Profit

@ngbrown
Copy link

ngbrown commented Apr 4, 2022

@MirahImage Can you test against a few well known providers? Such as Azure AD, Google G Suite, Auth0, etc. I got so far as getting Azure OAuth tokens working against rabbitmq_auth_backend_oauth2.

The way permissions are accepted only in an array is not ideal. Normally, in OAuth 2/OpenID, the requested, and authorized, scopes are echoed back in an space delimited scp field.

I got the current plugin to work using the Azure specific roles field, even this was not ideal as each permission had to be added as a separate role. Having lots of RabbitMQ specific roles for each read and write pattern you want to add really doesn't map to how roles should be managed.

I wanted a lookup table in the RabbitMQ config file that mapped specific scopes in the scp field, or an entry in some other array or space delimited field, to an expanded list of actual RabbitMQ permissions.

@MarcialRosales
Copy link
Contributor

@ngbrown We are in the process of testing against more providers. Auth0 is already tested. You can check it out here. However, we have only tested it against the messaging protocols such as AMQP, not against the management ui.

With regards the format of permissions, it can be a json array or a space-separated list of scopes within a single string. And RabbitMQ can be configured to read those permissions/scopes from a configurable field name such as scp rather than the standard name scopes.

The OAuth2 specification does not say whether the scopes should be treated as roles. You are right that Azure uses roles but Oauth0 uses permissions though. I do understand what you propose which is that RabbitMQ resolves role names specified in the JWT token into RabbitMQ permissions. However, roles tends to be very dynamic not something we statically define in a configuration file. What you are asking seems to be possible to do in Azure using groups and role assignments to group and maybe when you assign a user to a group, that user automatically gets all the "roles" -which in our case would be permissions- assigned to him. This is the kind of role mapping done by Identity providers like Azure.

@ngbrown
Copy link

ngbrown commented Apr 4, 2022

In Azure, it was possible to use the roles field and then assign users by group. You have to have a separate role per permission pattern in RabbitMQ. You also have to prefix the pattern with the application ID URI (ending with a .) for RabbitMQ.

I did try to use the scopes request and the scp response, but the issue there, was that Azure insisted on prefixing the application ID URI and separated with a / while RabbitMQ wanted a period (.).

Attempt to use scope/scp but didn't work, looked like this: api://e280b497-4249-4fc0-ab84-e8b5c572872e/read%3Agroup1%2F%2A.

So then adding to the roles array, you add them like this: api://e280b497-4249-4fc0-ab84-e8b5c572872e.read:group1/*. Which I guess is workable, but if you have a few permission patterns, and a few user groups, you have a combinatorial (Patterns x Groups).

I look forward to the management UI being able to participate in SSO via other providers such as Azure AD.

@lukebakken
Copy link
Collaborator

I got so far as getting Azure OAuth tokens working against rabbitmq_auth_backend_oauth2.

@ngbrown it would be very helpful to share a project demonstrating this.

Testing OAuth against several providers is extremely time consuming to set up and maintain. Anything users can do to assist will speed up that process is appreciated.

@MarcialRosales
Copy link
Contributor

Hi @ngbrown , we are working on supporting scope mapping so that your tokens may carry scopes in any format your Idp requires and yet we can configure RabbitMQ to map those custom scopes into RabbitMq's scopes.

This work is being track here #4588 should you had any comments.

@baptistedaroit
Copy link

Hello @ngbrown, @MarcialRosales, @MirahImage,

I am currently trying to use Azure AD to authenticate user to the UI management but I am blocked because of the issue mentioned here: I am redirected to uaa_location/oauth/authorize while Azure AD authorization endpoint is exposed at uaa_location/oauth2/authorize or uaa_location/oauth2/v2.0/authorize.

Is there currently a way to be update the expected endpoints so that I would be redirected to the right one?

@ngbrown: from your previous posts, I understand that you managed to overcome it. Is it the case?

Thanks for your help!

@MarcialRosales
Copy link
Contributor

HI @baptistedaroit. we are currently working on a new version of the management plugin and the oauth2 plugin precisely because of the issues you are experiencing.

For your reference, this work is being carried out on this branch https://github.com/rabbitmq/rabbitmq-server/tree/oidc-integration. Also, the oauth2 tutorial (https://github.com/rabbitmq/rabbitmq-oauth2-tutorial/tree/oidc-integration) is being updated to reflect the new work done in the oidc branch.
The minimum configuration required looked like this :

 {rabbitmq_management, [
     {oauth_enable, true},
     {oauth_client_id, "rabbitmq-client-code"},
     {oauth_client_secret, "X2ZqbZYKHq7WP8vsStr23jx6mtukt14g"},
     {oauth_provider_url, "http://0.0.0.0:8080/realms/test"}

Oauth2 implicit flow is deprecated. OAuth2 authorization code is supported. And authorization code with PKCE will be supported too. oauth_provider_url is the base url your Oauth2 server which must be OpenID Connect compliant. Thru this endpoint, we discover all the other endpoints such as authorize or logout.

By the way, the oidc-integration branch is based on 3.10.x branch. This work is still in development. Feel free if you are interested in testing it against Azure AD. Our plan is to eventually test it against Azure.

@baptistedaroit
Copy link

Hi @MarcialRosales,

Thanks a lot for all your inputs.

So far, I have been able to configure RabbitMQ to use Azure AD as OAuth Backend for the Management UI.

I am quite new on Azure AD and OAuth2 in general so I wrote kind of a documentation to describe all the steps needed to set it up. Would you like me to enrich the tutorials to provide guidance for people who could be interested?

@sahilsachdeva
Copy link

@baptistedaroit that would be helpful for me and i guess others as well. Can you please post your documentation?

@MarcialRosales
Copy link
Contributor

@baptistedaroit definitely you are very welcome to expand the tutorial. Did you get it to work using the official docker image? or did you use the oidc-integration branch that I have been working on recently?

@baptistedaroit
Copy link

@MarcialRosales, I get it to work using the oidc-integration branch you mentioned (I built a docker image based on it and did my tests using it). Sure, I need to format it properly and I will raise a PR to the tutorial repo (cc @sahilsachdeva)

@MarcialRosales
Copy link
Contributor

Awesome ! @baptistedaroit . In that case, feel free to create a PR to add another integration use case, in your case Azure. You know that we have under use-cases a folder dedicated to each Idp. Add one for Azure and then link it to the main Readme. If you can provide screenshots even better. I think I should do that with Oauth0 as it is not easy to explain it in plain words the amount of steps involved. But hey, that is just a suggestion :)

@baptistedaroit
Copy link

@MarcialRosales

Thanks for the guidance!

I opened a PR here.

Feel free to comment so I can adjust it if needed :)

@MarcialRosales
Copy link
Contributor

@baptistedaroit Thank you so much for the amount of work you have put !! I am reviewing it today.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants