Skip to content

Commit 706fa08

Browse files
Add scope aliases
to the docs and examples
1 parent 5ae12fe commit 706fa08

File tree

3 files changed

+77
-101
lines changed

3 files changed

+77
-101
lines changed

docs/oauth2-examples-okta.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ Once you've added the user to the appropriate groups and apps, they should have
152152

153153
The configuration on Okta side is done. You now have to configure RabbitMQ to use the resources you just created.
154154

155-
[rabbitmq.conf](https://github.com/rabbitmq/rabbitmq-oauth2-tutorial/tree/main/conf/okta/rabbitmq.conf) is a RabbitMQ configuration to **enable okta as OAuth 2.0 authentication backend** for the RabbitMQ OAuth2 and Management plugins. And [advanced.config](https://github.com/rabbitmq/rabbitmq-oauth2-tutorial/tree/main/conf/okta/advanced.config) is the RabbitMQ advanced configuration that maps RabbitMQ scopes to the permissions previously configured in Okta.
155+
[rabbitmq.conf](https://github.com/rabbitmq/rabbitmq-oauth2-tutorial/tree/main/conf/okta/rabbitmq.conf) is a RabbitMQ configuration to **enable okta as OAuth 2.0 authentication backend** for the RabbitMQ OAuth2 and Management plugins.
156156

157157
Update it with the following values (you should have noted these in the previous steps):
158158

docs/oauth2-examples/index.md

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

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

533-
In this use case you are going to demonstrate how to configure RabbitMQ to handle
534-
*custom scopes*. But what are *custom scopes*? They are any
535-
scope whose format is not compliant with RabbitMQ format. For instance, `api://rabbitmq:Read.All`
536-
is one of the custom scopes you will use in this use case.
537-
538-
#### How to Configure RabbitMQ to Use a Custom Scope Mapping
539-
540-
Starting with [RabbitMQ `3.10.0`](https://github.com/rabbitmq/rabbitmq-server/releases/tag/v3.10.0),
541-
the OAuth 2.0 plugin supports mapping of a scope aliases (arbitrary scope values or "names") to one or more scopes
542-
in the format that follows the RabbitMQ OAuth 2.0 plugin conventions.
543-
544-
See below a sample RabbitMQ configuration where you map `api://rabbitmq:Read.All`
545-
custom scope to `rabbitmq.read:*/*` RabbitMQ scope.
546-
547-
``` erl
548-
{rabbitmq_auth_backend_oauth2, [
549-
%%...,
550-
{scope_aliases, #{
551-
<<"api://rabbitmq:Read.All">> => [<<"rabbitmq.read:*/*">>],
552-
...
553-
},
554-
%%...
555-
]}
556-
```
557-
558-
Additionally, you can map a custom scope to many RabbitMQ scopes. For instance below you
559-
are mapping the role `api://rabbitmq:producer` to 3 RabbitMQ scopes which grants
560-
`read`, `write` and `configure` access on any resource and on any vhost:
561-
562-
``` erl
563-
{rabbitmq_auth_backend_oauth2, [
564-
%% ...,
565-
566-
{scope_aliases, #{
567-
<<"api://rabbitmq:producer">> => [
568-
<<"rabbitmq.read:*/*">>,
569-
<<"rabbitmq.write:*/*">>,
570-
<<"rabbitmq.configure:*/*">>
571-
]
572-
}},
573-
%% ...
574-
]}
575-
```
576-
577-
#### Scopes Aliases in JWT Tokens
578-
579-
If you do not configure RabbitMQ OAuth 2.0 plugin with `extra_scopes_source`, RabbitMQ
580-
expects the `scope` token's field to carry *custom scopes*. For instance, below you have a sample JWT
581-
token where the custom scopes are in the `scope` field :
533+
This example demonstrates how to use custom scopes with RabbitMQ.
534+
**UAA** identity provider has been configured with two clients (`producer_with_roles`
535+
and `consumer_with_roles`) with the following custom scopes:
536+
`producer_with_roles` with
537+
- `api://rabbitmq:producer`.
538+
539+
`consumer_with_roles` with
540+
- `api://rabbitmq:Read.All`.
541+
- `api://rabbitmq:Write.All`.
542+
- `api://rabbitmq:Configure.All`.
543+
- `api://rabbitmq:Administrator`.
544+
545+
For more information about scope aliases, check out
546+
the [section](./oauth2#scope-aliases) that explains it in more detail.
547+
548+
#### How to Configure Scope Aliases
549+
550+
This is the configuration required to map those custom scopes to RabbitMQ scopes.
551+
552+
:::tip
553+
Since RabbitMQ 4.1, it is possible to configure **scope aliases** using the [ini-like](./configure#config-file) configuration style. Earlier versions only supported
554+
the legacy Erlang-style.
555+
:::
582556

583-
```javascript
584-
{
585-
"sub": "producer",
586-
"scope": [
587-
"api://rabbitmq:producer",
588-
"api://rabbitmq:Administrator"
589-
],
590-
"aud": [
591-
"rabbitmq"
592-
]
593-
}
594-
```
557+
```ini
558+
auth_oauth2.scope_aliases.1.alias = api://rabbitmq:Read.All
559+
auth_oauth2.scope_aliases.1.scope = rabbitmq.read:*/*
595560

596-
Now, let's say you do configure RabbitMQ OAuth 2.0 plugin with `extra_scopes_source` as shown below:
561+
auth_oauth2.scope_aliases.2.alias = api://rabbitmq:Write.All
562+
auth_oauth2.scope_aliases.2.scope = rabbitmq.write:*/*
597563

564+
auth_oauth2.scope_aliases.3.alias = api://rabbitmq:Configure.All
565+
auth_oauth2.scope_aliases.3.scope = rabbitmq.configure:*/*
598566

599-
```ini
600-
# ...
601-
auth_oauth2.resource_server_id = rabbitmq
602-
auth_oauth2.additional_scopes_key = roles
603-
# ...
604-
```
567+
auth_oauth2.scope_aliases.3.alias = api://rabbitmq:Administrator
568+
auth_oauth2.scope_aliases.3.scope = rabbitmq.tag:administrator
605569

606-
With this configuration, RabbitMQ expects *custom scopes* in the field `roles` and
607-
the `scope` field is ignored.
570+
auth_oauth2.scope_aliases.4.alias = api://rabbitmq:producer
571+
auth_oauth2.scope_aliases.4.scope = rabbitmq.read:*/* rabbitmq.write:*/* rabbitmq.configure:*/* rabbitmq.tag:management
608572

609-
```javascript
610-
{
611-
"sub": "rabbitmq-client-code",
612-
"roles": "api://rabbitmq:Administrator.All",
613-
"aud": [
614-
"rabbitmq"
615-
]
616-
}
617573
```
618574

619-
#### UAA Configuration
620-
621-
To demonstrate this new capability you have configured UAA with two Oauth 2.0 clients. One
622-
called `producer_with_roles` with the *custom scope* `api://rabbitmq:producer` and `consumer_with_roles` with
623-
`api://rabbitmq:Read:All,api://rabbitmq:Configure:All,api://rabbitmq:Write:All`.
624-
> You are granting configure and write permissions to the consumer because you have configured perf-test to declare
625-
resources regardless whether it is a producer or consumer application.
626575

627-
These two uaac commands declare the two OAuth 2.0 clients above. You are adding an extra scope called `rabbitmq.*` so
628-
that UAA populates the JWT claim `aud` with the value `rabbitmq`. RabbitMQ expects `aud` to match the value you
629-
configure RabbitMQ with in the `resource_server_id` field.
576+
#### Test scope aliases
630577

631-
```bash
632-
uaac client add producer_with_roles --name producer_with_roles \
633-
--authorities "rabbitmq.*,api://rabbitmq:producer,api://rabbitmq:Administrator" \
634-
--authorized_grant_types client_credentials \
635-
--secret producer_with_roles_secret
636-
uaac client add consumer_with_roles --name consumer_with_roles \
637-
--authorities "rabbitmq.* api://rabbitmq:read:All" \
638-
--authorized_grant_types client_credentials \
639-
--secret consumer_with_roles_secret
640-
```
641578

642579

643580
#### RabbitMQ Configuration

docs/oauth2.md

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ In chronological order, here is the sequence of events that occur when a client
138138
| `auth_oauth2.resource_server_id` | The [Resource Server ID](#resource-server-id)
139139
| `auth_oauth2.resource_server_type` | The Resource Server Type required when using [Rich Authorization Request](#rich-authorization-request) token format
140140
| `auth_oauth2.additional_scopes_key` | Configure the plugin to look for scopes in other fields (maps to `additional_rabbitmq_scopes` in the old format). |
141-
| `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. |
141+
| `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.
142+
| `auth_oauth2.scope_aliases` | [Configure scope aliases](#scope-aliases).
142143
| `auth_oauth2.preferred_username_claims` | [List of the JWT claims](#preferred-username-claims) to look for the username associated with the token.
143144
| `auth_oauth2.default_key` | ID of the default signing key.
144145
| `auth_oauth2.signing_keys` | Paths to the [signing key files](#signing-key-files).
@@ -188,6 +189,43 @@ auth_oauth2.scope_prefix = ''
188189
...
189190
```
190191

192+
#### Scope aliases {#scope-aliases}
193+
194+
An scope alias is a mapping between a custom scope and a RabbitMQ's scope. A custom
195+
scope is any scope which is not recogonized by RabbitMQ.
196+
197+
Scope aliases are necessary when you can create RabbitMQ scopes in your
198+
identity provider. Instead you have to name scopes following a format which is not
199+
recognizable by RabbitMQ.
200+
201+
For instance, say you have these two roles in your identity provider:
202+
- `admin`.
203+
- `developer`.
204+
An OAuth token may carry those roles in the claim `scope` or in the claim `roles`.
205+
Either way you want to map those roles to the following RabbitMQ scopes:
206+
- `admin` to `rabbitmq.tag:administrator rabbitmq.read:*/`
207+
- `developer` to `rabbitmq.tag:management rabbitmq.read:*/* rabbitmq.write:*/* rabbitmq.configure:*/*`
208+
209+
You configure the scope aliases as follows. The mapping can be 1:1 or 1:many:
210+
```ìni
211+
# ...
212+
auth_oauth2.scope_prefix = rabbitmq.
213+
auth_oauth2.scope_aliases.admin = rabbitmq.tag:administrator rabbitmq.read:*/
214+
auth_oauth2.scope_aliases.developer = rabbitmq.tag:management rabbitmq.read:*/* rabbitmq.write:*/* rabbitmq.configure:*/*
215+
# ...
216+
```
217+
218+
Sometimes, the alias is not made of a single word but instead it uses special characters
219+
and symbols such as `api://admin` or `api://developer`. In those cases, you can configure the scope aliases as follows:
220+
# ...
221+
auth_oauth2.scope_prefix = rabbitmq.
222+
auth_oauth2.scope_aliases.1.alias = api://admin
223+
auth_oauth2.scope_aliases.1.scope = rabbitmq.tag:administrator rabbitmq.read:*/
224+
auth_oauth2.scope_aliases.2.alias = api://developer
225+
auth_oauth2.scope_aliases.2.scope = rabbitmq.tag:management rabbitmq.read:*/* rabbitmq.write:*/* rabbitmq.configure:*/*
226+
# ...
227+
```
228+
191229
#### Signing keys files {#signing-key-files}
192230
193231
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).
@@ -230,12 +268,13 @@ Each `auth_oauth2.resource_servers.<id/index>.` entry has the following variable
230268
| `resource_server_type` | The Resource Server Type required when using [Rich Authorization Request](#rich-authorization-request) token format.
231269
| `additional_scopes_key` | Configure the plugin to look for scopes in other fields (maps to `additional_rabbitmq_scopes` in the old format).
232270
| `scope_prefix` | [Configure the prefix for all scopes](#scope-prefix). The default value is `auth_oauth2.resource_server_id` followed by the dot `.` character.
271+
| `scope_aliases` | [Configure scope aliases](#scope_aliases)
233272
| `preferred_username_claims` | [List of the JWT claims](#preferred-username-claims) to look for the username associated with the token separated by commas.
234273
| `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.
235274

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

238-
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`.
277+
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`.
239278

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

0 commit comments

Comments
 (0)