Skip to content

Commit e98187c

Browse files
authored
Merge pull request #799 from DuendeSoftware/wca/enforcing-resource-isolation
Clarify what RequireResourceIndicator actually does
2 parents 8e70fed + b20fd26 commit e98187c

File tree

1 file changed

+36
-12
lines changed
  • src/content/docs/identityserver/fundamentals/resources

1 file changed

+36
-12
lines changed

src/content/docs/identityserver/fundamentals/resources/isolation.md

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ redirect_from:
1414
This is an Enterprise Edition feature.
1515
:::
1616

17-
OAuth itself only knows about scopes - the (API) resource concept does not exist from a pure protocol point of view. This means that all the requested scope and audience combination get merged into a single access token. This has a couple of downsides, e.g.
17+
OAuth itself only knows about scopes - the (API) resource concept does not exist from a pure protocol point of view.
18+
This means that all the requested scope and audience combination get merged into a single access token.
19+
This has a couple of downsides:
1820

1921
* tokens can become very powerful (and big)
2022
* if such a token leaks, it allows access to multiple resources
@@ -23,13 +25,15 @@ OAuth itself only knows about scopes - the (API) resource concept does not exist
2325
* resource specific processing like signing or encryption algorithms conflict
2426
* without sender-constraints, a resource could potentially re-use (or abuse) a token to call another contained resource directly
2527

26-
To solve this problem [RFC 8707](https://tools.ietf.org/html/rfc8707) adds another request parameter for the authorize and token endpoint called `resource`. This allows requesting a token for a specific resource (in other words - making sure the audience claim has a single value only, and all scopes belong to that single resource).
28+
To solve this problem [RFC 8707](https://tools.ietf.org/html/rfc8707) adds another request parameter for the authorize and token endpoint called `resource`.
29+
This allows requesting a token for a specific resource (in other words - making sure the audience claim has a single
30+
value only, and all scopes belong to that single resource).
2731

2832
## Using The Resource Parameter
2933

3034
Let's assume you have the following resource design and that the client is allowed access to all scopes:
3135

32-
```cs
36+
```csharp title="ApiResources.cs"
3337
var resources = new[]
3438
{
3539
new ApiResource("urn:invoices")
@@ -44,10 +48,12 @@ var resources = new[]
4448
};
4549
```
4650

47-
If the client would request a token for the `read` scope, the resulting access token would contain the audience of both the invoice and the products API and thus be accepted at both APIs.
51+
If the client would request a token for the `read` scope, the resulting access token would contain the audience of both
52+
the invoice and the products API and thus be accepted at both APIs.
4853

4954
### Machine to Machine Scenarios
50-
If the client in addition passes the `resource` parameter specifying the name of the resource where it wants to use the access token, the token engine can `down-scope` the resulting access token to the single resource, e.g.:
55+
If the client in addition passes the `resource` parameter specifying the name of the resource where it wants to use
56+
the access token, the token engine can `down-scope` the resulting access token to the single resource, e.g.:
5157

5258
```text
5359
POST /token
@@ -112,7 +118,8 @@ redirect_uri=...&
112118
resource=urn:invoices
113119
```
114120

115-
Which will return an access token for the invoices API and a refresh token. If you want to also retrieve the access token for the products API, you use the refresh token and make another roundtrip to the token endpoint.
121+
This will return an access token for the invoices API and a refresh token. If you want to also retrieve the access token
122+
for the products API, you use the refresh token and make another roundtrip to the token endpoint.
116123

117124
```text
118125
POST /token
@@ -125,24 +132,41 @@ refresh_token=...&
125132
resource=urn:products
126133
```
127134

128-
The end-result will be that the client has two access tokens - one for each resource and can manage their lifetime via the refresh token.
135+
The end-result will be that the client has two access tokens - one for each resource and can manage their lifetime via the refresh token.
129136

130137
## Enforcing Resource Isolation
131-
All examples so far used the `resource` parameter optionally. If you have API resources, where you want to make sure they are not sharing access tokens with other resources, you can enforce the resource indicator, e.g.:
138+
All examples so far used the `resource` parameter optionally. If you have API resources, where you want to make sure
139+
they are not sharing access tokens with other resources, you can enforce the resource indicator, e.g.:
132140

133-
```cs
141+
```csharp title="ApiResources.cs" {6,12}
134142
var resources = new[]
135143
{
136144
new ApiResource("urn:invoices")
137145
{
138146
Scopes = { "read", "write" },
139-
140147
RequireResourceIndicator = true
141148
},
142149

143150
new ApiResource("urn:products")
144151
{
145-
Scopes = { "read", "write" }
152+
Scopes = { "read", "write" },
153+
RequireResourceIndicator = true
146154
}
147155
};
148-
```
156+
```
157+
158+
The `RequireResourceIndicator` property **does not** mean that clients are forced to send the `resource` parameter when
159+
they request scopes associated with the API resource. You can still request those scopes without setting the `resource`
160+
parameter (or including the resource), and IdentityServer will issue a token as long as the client is allowed to request
161+
the scopes.
162+
163+
Instead, `RequireResourceIndicator` controls **when** the resource's URI is included in the **audience claim** (`aud`)
164+
of the issued access token.
165+
166+
* When `RequireResourceIndicator` is `false` (the default):
167+
IdentityServer **automatically includes** the API's resource URI in the token's audience if any of the resource's scopes
168+
are requested, even if the `resource` parameter was not sent in the request or didn't contain the resource URI.
169+
* When `RequireResourceIndicator` is `true`:
170+
The API's resource URI will **only** be included in the audience **if the client explicitly includes the resource URI**
171+
via the `resource` parameter when requesting the token.
172+

0 commit comments

Comments
 (0)