Skip to content

Commit e369988

Browse files
Update everything related to scope aliases
1 parent d622524 commit e369988

File tree

3 files changed

+89
-106
lines changed

3 files changed

+89
-106
lines changed

docs/oauth2-examples-okta.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,12 +195,9 @@ For that, you will need the following values from the previous steps:
195195
* **okta-Issuer**: the **default Authorization server**
196196
* **okta-Metadata-URI**: the **default Authorization server**
197197

198-
Copy [rabbitmq.conf.tmpl](https://github.com/rabbitmq/rabbitmq-oauth2-tutorial/tree/main/conf/okta/rabbitmq.conf.tmpl) from the tutorial repository
198+
Copy [rabbitmq.conf.tmpl](https://github.com/rabbitmq/rabbitmq-oauth2-tutorial/tree/next/conf/okta/rabbitmq.conf.tmpl) from the tutorial repository
199199
to `rabbitmq.conf`. It must be in the same directory as `rabbitmq.conf.tmpl`.
200200

201-
There is a second configuration file, [advanced.config](https://github.com/rabbitmq/rabbitmq-oauth2-tutorial/tree/main/conf/okta/advanced.config),
202-
that will not need any modifications. This is the RabbitMQ [advanced configuration file](./configure/) where RabbitMQ scopes are mapped to the permissions previously configured in Okta.
203-
204201
Edit `rabbitmq.conf` and proceed as follows:
205202

206203
1. Replace `{okta_client_app_ID}` with your **okta_client_app_ID**
@@ -210,6 +207,15 @@ or `{okta-issuer}/.well-known/openid-configuration`
210207
4. Else you need to determine the path that follows the uri in `{okta-issuer}` and update
211208
`auth_oauth2.discovery_endpoint_path` accordingly. For instance, if **okta-Metadata-URI** is `{okta-issuer}/some-other-endpoint`, you update `auth_oauth2.discovery_endpoint_path` with the value `some-other-endpoint`.
212209

210+
The mapping of the roles configured in okta, i.e. `monitoring` and `admin`, are configured
211+
at the bottom of the `rabbitmq.conf` file. Here it is configuration for convenience:
212+
213+
```ini
214+
#...
215+
auth_oauth2.scope_aliases.admin = okta.read:*/* okta.write:*/* okta.configure:*/* okta.tag:administrator
216+
auth_oauth2.scope_aliases.monitoring = okta.tag:management okta.read:*/
217+
#...
218+
```
213219

214220
### About the OpenId Discovery Endpoint
215221

docs/oauth2-examples/index.md

Lines changed: 30 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -530,116 +530,57 @@ make curl-with-token URL=http://localhost:15672/api/overview TOKEN=$(bin/jwt_tok
530530

531531
### Using Scope Aliases {#using-scope-aliases}
532532

533-
*Custom scopes*? are any scope whose format is not compliant with RabbitMQ format.
534-
For instance, `api://rabbitmq:Read.All` is one of the custom scopes you will use in this use case.
533+
This example demonstrates how to use custom scopes with RabbitMQ.
535534

536-
#### How to Configure RabbitMQ to Use a Custom Scope Mapping
535+
**UAA** identity provider has been configured with two clients (`producer_with_roles`
536+
and `consumer_with_roles`) with the following custom scopes:
537537

538-
See below a sample RabbitMQ configuration where you map `api://rabbitmq:Read.All`
539-
custom scope to `rabbitmq.read:*/*` RabbitMQ scope.
538+
`producer_with_roles` with
539+
- `api://rabbitmq:producer`.
540540

541-
``` erl
542-
{rabbitmq_auth_backend_oauth2, [
543-
%%...,
544-
{scope_aliases, #{
545-
<<"api://rabbitmq:Read.All">> => [<<"rabbitmq.read:*/*">>],
546-
...
547-
},
548-
%%...
549-
]}
550-
```
551-
552-
Additionally, you can map a custom scope to many RabbitMQ scopes. For instance below you
553-
are mapping the role `api://rabbitmq:producer` to 3 RabbitMQ scopes which grants
554-
`read`, `write` and `configure` access on any resource and on any vhost:
555-
556-
``` erl
557-
{rabbitmq_auth_backend_oauth2, [
558-
%% ...,
559-
560-
{scope_aliases, #{
561-
<<"api://rabbitmq:producer">> => [
562-
<<"rabbitmq.read:*/*">>,
563-
<<"rabbitmq.write:*/*">>,
564-
<<"rabbitmq.configure:*/*">>
565-
]
566-
}},
567-
%% ...
568-
]}
569-
```
570-
571-
#### Scopes Aliases in JWT Tokens
541+
`consumer_with_roles` with
542+
- `api://rabbitmq:Read.All`.
543+
- `api://rabbitmq:Write.All`.
544+
- `api://rabbitmq:Configure.All`.
545+
- `api://rabbitmq:Administrator`.
572546

573-
If you do not configure RabbitMQ OAuth 2.0 plugin with `extra_scopes_source`, RabbitMQ
574-
expects the `scope` token's field to carry *custom scopes*. For instance, below you have a sample JWT
575-
token where the custom scopes are in the `scope` field :
547+
For more information about scope aliases, check out
548+
the [section](./oauth2#scope-aliases) that explains it in more detail.
576549

577-
```javascript
578-
{
579-
"sub": "producer",
580-
"scope": [
581-
"api://rabbitmq:producer",
582-
"api://rabbitmq:Administrator"
583-
],
584-
"aud": [
585-
"rabbitmq"
586-
]
587-
}
588-
```
550+
#### How to Configure Scope Aliases
589551

590-
Now, let's say you do configure RabbitMQ OAuth 2.0 plugin with `extra_scopes_source` as shown below:
552+
This is the configuration required to map those custom scopes to RabbitMQ scopes.
591553

554+
:::tip
555+
Since RabbitMQ 4.1, it is possible to configure **scope aliases** using the [ini-like](./configure#config-file) configuration style. Earlier versions only supported
556+
the legacy Erlang-style.
557+
:::
592558

593559
```ini
594-
# ...
595-
auth_oauth2.resource_server_id = rabbitmq
596-
auth_oauth2.additional_scopes_key = roles
597-
# ...
598-
```
599-
600-
With this configuration, RabbitMQ expects *custom scopes* in the field `roles` and
601-
the `scope` field is ignored.
560+
auth_oauth2.scope_aliases.1.alias = api://rabbitmq:Read.All
561+
auth_oauth2.scope_aliases.1.scope = rabbitmq.read:*/*
602562

603-
```javascript
604-
{
605-
"sub": "rabbitmq-client-code",
606-
"roles": "api://rabbitmq:Administrator.All",
607-
"aud": [
608-
"rabbitmq"
609-
]
610-
}
611-
```
563+
auth_oauth2.scope_aliases.2.alias = api://rabbitmq:Write.All
564+
auth_oauth2.scope_aliases.2.scope = rabbitmq.write:*/*
612565

613-
#### UAA Configuration
566+
auth_oauth2.scope_aliases.3.alias = api://rabbitmq:Configure.All
567+
auth_oauth2.scope_aliases.3.scope = rabbitmq.configure:*/*
614568

615-
To demonstrate this new capability you have configured UAA with two Oauth 2.0 clients. One
616-
called `producer_with_roles` with the *custom scope* `api://rabbitmq:producer` and `consumer_with_roles` with
617-
`api://rabbitmq:Read:All,api://rabbitmq:Configure:All,api://rabbitmq:Write:All`.
618-
> You are granting configure and write permissions to the consumer because you have configured perf-test to declare
619-
resources regardless whether it is a producer or consumer application.
569+
auth_oauth2.scope_aliases.3.alias = api://rabbitmq:Administrator
570+
auth_oauth2.scope_aliases.3.scope = rabbitmq.tag:administrator
620571

621-
These two uaac commands declare the two OAuth 2.0 clients above. You are adding an extra scope called `rabbitmq.*` so
622-
that UAA populates the JWT claim `aud` with the value `rabbitmq`. RabbitMQ expects `aud` to match the value you
623-
configure RabbitMQ with in the `resource_server_id` field.
572+
auth_oauth2.scope_aliases.4.alias = api://rabbitmq:producer
573+
auth_oauth2.scope_aliases.4.scope = rabbitmq.read:*/* rabbitmq.write:*/* rabbitmq.configure:*/* rabbitmq.tag:management
624574

625-
```bash
626-
uaac client add producer_with_roles --name producer_with_roles \
627-
--authorities "rabbitmq.*,api://rabbitmq:producer,api://rabbitmq:Administrator" \
628-
--authorized_grant_types client_credentials \
629-
--secret producer_with_roles_secret
630-
uaac client add consumer_with_roles --name consumer_with_roles \
631-
--authorities "rabbitmq.* api://rabbitmq:read:All" \
632-
--authorized_grant_types client_credentials \
633-
--secret consumer_with_roles_secret
634575
```
635576

636577

637578
#### RabbitMQ Configuration
638579

639580
In the OAuth 2.0 tutorial repository, there are two RabbitMQ configuration files ready to be used, for UAA:
640581

641-
- [conf/uaa/advanced-scope-aliases.config](https://github.com/rabbitmq/rabbitmq-oauth2-tutorial/blob/main/conf/uaa/advanced-scope-aliases.config): configures a set of scope aliases.
642-
- [conf/uaa/rabbitmq.conf](https://github.com/rabbitmq/rabbitmq-oauth2-tutorial/blob/main/conf/uaa/rabbitmq.conf) : configure the rest of oauth2 configuration in addition to configuring `extra_scope` as another claim from where to read scopes from
582+
- [conf/uaa/scope-aliases.conf](https://github.com/rabbitmq/rabbitmq-oauth2-tutorial/blob/next/conf/uaa/scope-aliases.conf): configures a set of scope aliases.
583+
- [conf/uaa/rabbitmq.conf](https://github.com/rabbitmq/rabbitmq-oauth2-tutorial/blob/next/conf/uaa/rabbitmq.conf) : configure the rest of oauth2 configuration in addition to configuring `extra_scope` as another claim from where to read scopes from
643584

644585

645586
#### Demo 1: Launch RabbitMQ with custom scopes in scope field

docs/oauth2.md

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -146,18 +146,17 @@ In chronological order, here is the sequence of events that occur when a client
146146
|--------------------------------------------|-----------
147147
| `auth_oauth2.resource_server_id` | The [Resource Server ID](#resource-server-id)
148148
| `auth_oauth2.resource_server_type` | The Resource Server Type required when using [Rich Authorization Request](#rich-authorization-request) token format
149-
| `auth_oauth2.additional_scopes_key` | Configure the plugin to look for scopes in other fields (maps to `additional_rabbitmq_scopes` in the old format) |
150-
| `auth_oauth2.scope_prefix` | [Configure the prefix for all scopes](#scope-prefix). The default value is `auth_oauth2.resource_server_id` followed by the dot `.` character |
151-
| `auth_oauth2.preferred_username_claims` | [List of the JWT claims](#preferred-username-claims) to look for the username associated with the token
152-
| `auth_oauth2.default_key` | ID of the default signing key
153-
| `auth_oauth2.signing_keys` | Paths to the [signing key files](#signing-key-files)
154-
| `auth_oauth2.issuer` | The [issuer URL](#configure-issuer) of the authorization server. Used to build the discovery endpoint URL to discover other endpoints such as such as `jwks_uri`. Management UI users will be sent to this for logging in
155-
| `auth_oauth2.discovery_endpoint_path` | The path used for the [OpenId discovery endpoint](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata). The endpoint URI is built using `auth_oauth2.issuer`, this path or else the default path `.well-known/openid-configuration` followed by query parameters configured in the following variable
156-
| `auth_oauth2.discovery_endpoint_params` | [List of HTTP query parameters](#discovery-endpoint-params) sent to the OpenId discovery endpoint
157-
| `auth_oauth2.jwks_url` | The URL of the [JWKS endpoint](#jwks-endpoint). According to the [JWT Specification](https://datatracker.ietf.org/doc/html/rfc7515#section-4.1.2), the endpoint URL must use "https" for schema. Optional if you set `auth_oauth2.issuer`. If this URL is set, it overrides the `jwks_uri` discovered via the discovery endpoint
158-
| `auth_oauth2.token_endpoint` | The URL of the OAuth 2.0 token endpoint. Optional if you set `auth_oauth2.issuer`. If this URL is set, it overrides the `token_endpoint` discovered via the discovery endpoint
159-
| `auth_oauth2.https.cacertfile` | Path to a file containing PEM-encoded CA certificates. The CA certificates are used to connect to any of these endpoints: `jwks_url`, `token_endpoint`, or the discovery endpoint
160-
| `auth_oauth2.https.depth` | The maximum number of non-self-issued intermediate certificates that may follow the peer certificate in a valid [certification path](ssl#peer-verification-depth). The default value is 10
149+
| `auth_oauth2.additional_scopes_key` | Configure the plugin to look for scopes in other fields (maps to `additional_rabbitmq_scopes` in the old format). |
150+
| `auth_oauth2.scope_prefix` | [Configure the prefix for all scopes](#scope-prefix). The default value is `auth_oauth2.resource_server_id` followed by the dot `.` character.
151+
| `auth_oauth2.scope_aliases` | [Configure scope aliases](#scope-aliases). See this [example](./oauth2-examples#using-scope-aliases).
152+
| `auth_oauth2.preferred_username_claims` | [List of the JWT claims](#preferred-username-claims) to look for the username associated with the token.
153+
| `auth_oauth2.default_key` | ID of the default signing key.
154+
| `auth_oauth2.signing_keys` | Paths to the [signing key files](#signing-key-files).
155+
| `auth_oauth2.issuer` | The [issuer URL](#configure-issuer) of the authorization server that is used to discover endpoints such as `jwk_uri` and others (https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata).
156+
| `auth_oauth2.jwks_url` | The URL of the [JWKS endpoint](#jwks-endpoint). According to the [JWT Specification](https://datatracker.ietf.org/doc/html/rfc7515#section-4.1.2), the endpoint URL must be https.
157+
| `auth_oauth2.token_endpoint` | The URL of the OAuth 2.0 token endpoint.
158+
| `auth_oauth2.https.cacertfile` | Path to a file containing PEM-encoded CA certificates. The CA certificates are used to connect to any of these endpoints: `jwks_url`, `token_endpoint`, or the `issuer`.
159+
| `auth_oauth2.https.depth` | The maximum number of non-self-issued intermediate certificates that may follow the peer certificate in a valid [certification path](ssl#peer-verification-depth). The default value is 10.
161160
| `auth_oauth2.https.peer_verification` | Configures [peer verification](ssl#peer-verification). Available values: `verify_none`, `verify_peer`. The default value is `verify_peer` if there are trusted CA installed in the OS or `auth_oauth2.https.cacertfile` is set. <p/> **Deprecated**: This variable will be soon replaced by `auth_oauth2.https.verify`. Users should stop using this variable.
162161
| `auth_oauth2.https.fail_if_no_peer_cert` | Used together with `auth_oauth2.https.peer_verification = verify_peer`. When set to `true`, TLS connection will be rejected if the client fails to provide a certificate. The default value is `false`
163162
| `auth_oauth2.https.hostname_verification` | Enable wildcard-aware hostname verification for key server. Available values: `wildcard`, `none`. The default value is `none`
@@ -199,6 +198,42 @@ auth_oauth2.scope_prefix = ''
199198
...
200199
```
201200

201+
#### Scope aliases {#scope-aliases}
202+
203+
An scope alias is a mapping between a custom scope and a RabbitMQ's scope. A custom
204+
scope is any scope which is not recogonized by RabbitMQ.
205+
206+
Scope aliases are necessary when you cannot create RabbitMQ scopes in your
207+
identity provider. Instead you have to name them following a format which is not
208+
recognizable by RabbitMQ.
209+
210+
For instance, say you have these two roles in your identity provider:
211+
- `admin`.
212+
- `developer`.
213+
214+
Also say that you want to map those roles to the following RabbitMQ scopes:
215+
- `admin` to `rabbitmq.tag:administrator rabbitmq.read:*/`
216+
- `developer` to `rabbitmq.tag:management rabbitmq.read:*/* rabbitmq.write:*/* rabbitmq.configure:*/*`
217+
218+
You configure the scope aliases as follows. The mapping can be 1:1 or 1:many:
219+
```ìni
220+
# ...
221+
auth_oauth2.scope_aliases.admin = rabbitmq.tag:administrator rabbitmq.read:*/
222+
auth_oauth2.scope_aliases.developer = rabbitmq.tag:management rabbitmq.read:*/* rabbitmq.write:*/* rabbitmq.configure:*/*
223+
# ...
224+
```
225+
226+
Sometimes, the alias is not made of a single word but instead it uses special characters
227+
and symbols including the separator character `.`. In those cases, you can configure the scope aliases as follows:
228+
```ìni
229+
# ...
230+
auth_oauth2.scope_aliases.1.alias = api://admin
231+
auth_oauth2.scope_aliases.1.scope = rabbitmq.tag:administrator rabbitmq.read:*/
232+
auth_oauth2.scope_aliases.2.alias = api://developer.All
233+
auth_oauth2.scope_aliases.2.scope = rabbitmq.tag:management rabbitmq.read:*/* rabbitmq.write:*/* rabbitmq.configure:*/*
234+
# ...
235+
```
236+
202237
#### Signing keys files {#signing-key-files}
203238

204239
The following configuration declares two signing keys and configures the kid of the default signing key. For more information check the section [Configure Signing keys](#configure-signing-keys).
@@ -242,12 +277,13 @@ Each `auth_oauth2.resource_servers.<id/index>.` entry has the following variable
242277
| `resource_server_type` | The Resource Server Type required when using [Rich Authorization Request](#rich-authorization-request) token format.
243278
| `additional_scopes_key` | Configure the plugin to look for scopes in other fields (maps to `additional_rabbitmq_scopes` in the old format).
244279
| `scope_prefix` | [Configure the prefix for all scopes](#scope-prefix). The default value is `auth_oauth2.resource_server_id` followed by the dot `.` character.
280+
| `scope_aliases` | [Configure scope aliases](#scope-aliases)
245281
| `preferred_username_claims` | [List of the JWT claims](#preferred-username-claims) to look for the username associated with the token separated by commas.
246282
| `oauth_provider_id` | The identifier of the OAuth Provider associated to this resource. RabbitMQ uses the signing keys issued by this OAuth Provider to validate tokens whose audience matches this resource's id.
247283

248284
All available configurable parameters for each OAuth 2 provider is documented [in a separate section](#multiple-oauth-providers-configuration).
249285

250-
Usually, a numeric value is used as `index`, for example `auth_oauth2.resource_servers.1.id = rabbit_prod`. However, it can be any string, for example `auth_oauth2.resource_servers.rabbit_prod.jwks_url = http://some_url`. By default, the `index` is the resource server's id. However, you can override it via the `id` variable like in `auth_oauth2.resource_servers.1.id = rabbit_prod`.
286+
Usually, a numeric value is used as `index`, for example `auth_oauth2.resource_servers.1.id = rabbit_prod`. However, it can be any string, for example `auth_oauth2.resource_servers.rabbit_prod.issuer = http://some_url`. By default, the `index` is the resource server's id. However, you can override it via the `id` variable like in `auth_oauth2.resource_servers.1.id = rabbit_prod`.
251287

252288
Here is an example which configures two resources (`prod` and `dev`) which are used by the users and clients managed by
253289
the same identity provider whose issuer url is `https://my-idp.com/`:

0 commit comments

Comments
 (0)