Skip to content

Commit 6151e62

Browse files
authored
Merge pull request #18 from elf-pavlik/as-sequence
Add RS associated AS issuing Access Token
2 parents 9ac921a + 8a19057 commit 6151e62

File tree

7 files changed

+311
-256
lines changed

7 files changed

+311
-256
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
*.html
33
*.mmd.svg
44
publish
5+
node_modules

basic-flow-diagram.png

-50.6 KB
Binary file not shown.

index.bs

Lines changed: 93 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ that additional functionality is required.
6363

6464
The additional functionality documented herein aims to address:
6565

66-
1. Resource servers having no existing trust relationship with identity providers.
66+
1. Resource servers and their Authorization servers having no existing trust relationship with identity providers.
6767
2. Ephemeral Clients as a first-order use-case.
6868

6969
## Out of Scope ## {#intro-out-of-scope}
@@ -81,8 +81,9 @@ This specification uses the terms "access token", "authorization server", "resou
8181
"grant type", and "client" as defined by The OAuth 2.0 Authorization Framework [[!RFC6749]].
8282

8383
Throughout this specification, we will use the term Identity Provider (IdP) in line with the
84-
terminology used in the Open ID Connect Core 1.0 specification (OIDC) [[!OIDC.Core]]. It should be noted that
85-
The OAuth 2.0 Authorization Framework (OAuth) [[!RFC6749]] refers to this same entity as an Authorization Server.
84+
terminology used in the Open ID Connect Core 1.0 specification (OIDC) [[!OIDC.Core]].
85+
It should be noted that this is distinct from the entity referred to as an Authorization Server
86+
by the OAuth 2.0 Authorization Framework (OAuth) [[!RFC6749]].
8687

8788
This specification also uses the following terms:
8889

@@ -145,23 +146,11 @@ Solid and are used as a primary identifier for Users in this specification.
145146

146147
*This section is non-normative*
147148

148-
The basic authentication and authorization flow is as follows:
149-
150-
1. The Client requests a non-public resource from the RS.
151-
2. The RS returns a 401 with a `WWW-Authenticate` HTTP header containing parameters that inform the
152-
Client that a DPoP-bound Access Token is required.
153-
3. The Client presents its Client Identifier and the associated Secret, if any, to the IdP and requests an
154-
Authorization Code.
155-
4. If granted, the Client presents the Authorization Code and a DPoP proof, to the Token Endpoint.
156-
5. The Token Endpoint returns a DPoP-bound Access Token and OIDC ID Token, to the Client.
157-
6. The Client presents the DPoP-bound Access Token and DPoP proof, to the RS.
158-
7. The RS gets user's WebID Document and check for designated OIDC issuers
159-
8. The RS gets the public key from the IdP and uses it to validate the signature on the DPoP-bound Access Token (JWS).
160-
9. If IdP is designated by the user and Access Token is valid, then the RS returns the requested resource.
149+
Details of the flow are available in [[!Solid.OIDC.Primer]]
161150

162151
<figure id="fig-signature">
163152
<img src="sequence.mmd.svg" />
164-
<figcaption>Basic sequence of authentication and authorization as described above.</figcaption>
153+
<figcaption>Basic sequence of authenticating the user and the client.</figcaption>
165154
</figure>
166155

167156
# Client Identifiers # {#clientids}
@@ -180,9 +169,6 @@ provided at `https://www.w3.org/ns/solid/oidc-context.jsonld` such that the resu
180169
document produces a JSON serialization of an OIDC client registration, per the
181170
definition of client registration metadata from [[!RFC7591]] section 2.
182171

183-
Issue: [Related Issue](https://github.com/solid/authentication-panel/issues/75)
184-
Solid-OIDC requirements for client description document
185-
186172
Also, the IdP MUST dereference the Client ID Document and match any Client-supplied parameters
187173
with the values in the Client ID Document.
188174

@@ -192,7 +178,7 @@ list.
192178
This example uses [JSON-LD ](https://www.w3.org/TR/json-ld11/) for the Client ID Document:
193179

194180
<div class='example'>
195-
<p>https://app.example/id
181+
<p>https://app.example/id</p>
196182

197183
<pre highlight="jsonld">
198184
{
@@ -317,58 +303,35 @@ Assuming one of the following options
317303
- Client ID and Secret, and valid DPoP Proof (for dynamic and static registration)
318304
- Dereferencable Client Identifier with a proper Client ID Document and valid DPoP Proof (for a Solid client identifier)
319305

320-
the IdP MUST return two tokens to the Client:
321-
322-
1. A DPoP-bound Access Token
323-
2. An OIDC ID Token
324-
325-
## DPoP-bound Access Token ## {#tokens-access}
306+
the IdP MUST return A DPoP-bound OIDC ID Token.
326307

327-
The DPoP-bound Access Token MUST be a valid JWT. See also: [[!RFC7519]].
308+
## DPoP-bound OIDC ID Token ## {#tokens-id}
328309

329-
When requesting a DPoP-bound Access Token, the Client MUST send a DPoP proof JWT
310+
When requesting a DPoP-bound OIDC ID Token, the Client MUST send a DPoP proof JWT
330311
that is valid according to the [[DPOP#section-5]]. The DPoP proof JWT is used to
331-
bind the access token to a public key. See also: [[!DPOP]].
312+
bind the OIDC ID Token to a public key. See also: [[!DPOP]].
332313

333-
With the `webid` scope, the DPoP-bound Access Token payload MUST contain these claims:
314+
With the `webid` scope, the DPoP-bound OIDC ID Token payload MUST contain these claims:
334315
* `webid` — The WebID claim MUST be the user's WebID.
335316
* `iss` — The issuer claim MUST be a valid URL of the IdP
336317
instantiating this token.
337-
* `aud` — The audience claim MUST either be the string `solid` or be an array
338-
of values, one of which is the string `solid`. In the decentralized world
339-
of Solid OIDC, the principal of an access token is not a specific endpoint,
340-
but rather the Solid API; that is, any Solid server at any accessible address
318+
* `aud` — The audience claim MUST be an array of values,
319+
one of which is the ClientID claim is used to identify the client.
320+
(See also: [section 5. Client Identifiers](#clientids)).
321+
another one is the string `solid`.
322+
In the decentralized world
323+
of Solid OIDC, the audience of an ID Token is not only the client,
324+
but also a Solid Authorization Server;
325+
that is, any Solid Authorization Server at any accessible address
341326
on the world wide web. See also: [[RFC7519#section-4.1.3]].
327+
* `azp` - The ClientID claim is used to identify the client.
328+
(See also: [section 5. Client Identifiers](#clientids)).
342329
* `iat` — The issued-at claim is the time at which the DPoP-bound
343-
Access Token was issued.
330+
OIDC ID Token was issued.
344331
* `exp` — The expiration claim is the time at which the DPoP-bound
345-
Access Token becomes invalid.
332+
OIDC ID Token becomes invalid.
346333
* `cnf` — The confirmation claim is used to identify the DPoP Public
347-
Key bound to the Access Token. See also: [[DPOP#section-7]].
348-
* `client_id` - The ClientID claim is used to identify the client. See also:
349-
[section 5. Client Identifiers](#clientids).
350-
351-
<div class="example">
352-
<p>An example DPoP-bound Access Token:
353-
354-
<pre highlight="json">
355-
{
356-
"webid": "https://janedoe.com/web#id",
357-
"iss": "https://idp.example.com",
358-
"aud": "solid",
359-
"iat": 1541493724,
360-
"exp": 1573029723,
361-
"cnf":{
362-
"jkt":"0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I"
363-
},
364-
"client_id": "https://client.example.com/web#id"
365-
}
366-
</pre>
367-
</div>
368-
369-
## OIDC ID Token ## {#tokens-id}
370-
371-
When requesting the `webid` scope, the user's WebID MUST be present in the ID Token as the `webid` claim.
334+
Key bound to the OIDC ID Token. See also: [[DPOP#section-7]].
372335

373336
<div class="example">
374337
<p>An example OIDC ID Token:
@@ -378,45 +341,74 @@ When requesting the `webid` scope, the user's WebID MUST be present in the ID To
378341
"webid": "https://janedoe.com/web#id",
379342
"iss": "https://idp.example.com",
380343
"sub": "janedoe",
381-
"aud": "https://client.example.com/web#id",
382-
"nonce": "n-0S6_WzA2Mj",
383-
"exp": 1311281970,
344+
"aud": ["https://client.example.com/web#id", "solid"],
345+
"azp": "https://client.example.com/web#id",
384346
"iat": 1311280970,
347+
"exp": 1311281970,
348+
"cnf":{
349+
"jkt":"0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I"
350+
}
385351
}
386352
</pre>
387353
</div>
388354

389355
# Resource Access # {#resource}
390356

357+
## Authorization Server Discovery ## {#authorization-server-discovery}
358+
359+
When a Client performs an unauthenticated request to a protected resource,
360+
the Resource Server MUST respond with the HTTP <code>401</code> status code,
361+
and a <code>WWW-Authenticate</code> HTTP header. See also: [[RFC7235#section-4.1]]
362+
363+
The <code>WWW-Authenticate</code> HTTP header MUST include an <code>as_uri</code>
364+
parameter unless the authentication scheme requires a different mechanism
365+
for discovering an associated authorization server.
366+
367+
Authorization Servers SHOULD implement User-Managed Access (UMA) 2.0 Grant for
368+
OAuth 2.0 Authorization [[!UMA]].
369+
370+
## Obtaining an Access Token ## {#obtaining-access-token}
371+
372+
For Authorization Servers that conform to [[!UMA]], the
373+
<code>http://openid.net/specs/openid-connect-core-1_0.html#IDToken</code> profile MUST
374+
be supported. This profile MUST be advertised in the <code>uma_profiles_supported</code>
375+
metadata of the Authorization Server discovery document [[UMA#rfc.section.2]].
376+
377+
When using the <code>http://openid.net/specs/openid-connect-core-1_0.html#IDToken</code>
378+
profile with an UMA-based Authorization Server, the Authorization Server MUST be capable
379+
of exchanging a valid Solid-OIDC ID Token [[#tokens-id]] for an OAuth 2.0 Access Token.
380+
381+
Note: Clients can push additional claims by requesting an upgraded RPT [[UMA#rfc.section.3.3.1]]
382+
391383
## DPoP Proof Validation ## {#resource-dpop-validation}
392384

393385
A DPoP Proof that is valid according to
394386
[DPoP Internet-Draft, Section 4.3](https://tools.ietf.org/html/draft-ietf-oauth-dpop-04#section-4.3),
395-
MUST be present when a DPoP-bound Access Token is used.
387+
MUST be present when a DPoP-bound OIDC ID Token is used.
396388

397-
## Access Token Validation ## {#resource-access-validation}
389+
## OIDC ID Token Validation ## {#resource-access-validation}
398390

399-
The DPoP-bound Access Token MUST be validated according to
391+
The DPoP-bound OIDC ID Token MUST be validated according to
400392
[DPoP Internet-Draft, Section 6](https://tools.ietf.org/html/draft-ietf-oauth-dpop-04#section-6),
401-
but the RS MAY perform additional verification in order to determine whether to grant access to the
393+
but the AS MAY perform additional verification in order to determine whether to grant access to the
402394
requested resource.
403395

404396
The user's WebID in the `webid` claim MUST be dereferenced and checked against the `iss` claim in the
405-
Access Token. If the `iss` claim is different from the domain of the WebID, then the RS MUST check
397+
OIDC ID Token. If the `iss` claim is different from the domain of the WebID, then the AS MUST check
406398
the WebID document for the existence of a statement matching `?webid <http://www.w3.org/ns/solid/terms#oidcIssuer> ?iss.`,
407399
where `?webid` and `?iss` are the values of the `webid` and `iss` claims respectively.
408-
This prevents a malicious identity provider from issuing valid Access Tokens for arbitrary WebIDs.
400+
This prevents a malicious identity provider from issuing valid OIDC ID Tokens for arbitrary WebIDs.
409401

410-
Unless the RS acquires IdP keys through some other means, or the RS chooses to reject tokens issued by this IdP,
411-
the RS MUST follow OpenID Connect Discovery 1.0 [[!OIDC.Discovery]] to find an IdP's signing keys (JWK).
402+
Unless the AS acquires IdP keys through some other means, or the AS chooses to reject tokens issued by this IdP,
403+
the AS MUST follow OpenID Connect Discovery 1.0 [[!OIDC.Discovery]] to find an IdP's signing keys (JWK).
412404

413405
### WebID Issuer Discovery via Link Headers ### {#webid-issuer-discovery}
414406

415407
A server hosting a WebID document MAY transmit the `http://www.w3.org/ns/solid/terms#oidcIssuer` values via Link Headers but it MUST be the same as in the RDF representation. A client MUST treat the RDF in the body of the WebID document as canonical but MAY use the Link Header values as an optimization.
416408

417409
<div class="example">
418410
<pre highlight="http">
419-
Link: <https://oidc.example>; rel="http://www.w3.org/ns/solid/terms#oidcIssuer"; anchor="#id"
411+
Link: &lt;https://oidc.example&gt;; rel="http://www.w3.org/ns/solid/terms#oidcIssuer"; anchor="#id"
420412
</pre>
421413
</div>
422414

@@ -460,7 +452,7 @@ All tokens, Client, and User credentials MUST only be transmitted over TLS.
460452

461453
## Client IDs ## {#security-client-ids}
462454

463-
An RS SHOULD assign a fixed set of low trust policies to any client identified as anonymous.
455+
An AS SHOULD assign a fixed set of low trust policies to any client identified as anonymous.
464456

465457
Implementors SHOULD expire ephemeral Client IDs that are kept in server storage to mitigate the
466458
potential for a bad actor to fill server storage with unexpired or otherwise useless Client IDs.
@@ -479,15 +471,15 @@ among other factors, are what makes Client trust challenging.
479471

480472
# Privacy Considerations # {#privacy}
481473

482-
## Access Token Reuse ## {#privacy-token-reuse}
474+
## OIDC ID Token Reuse ## {#privacy-token-reuse}
483475

484476
*This section is non-normative*
485477

486-
With JWTs being extendable by design, there is potential for a privacy breach if Access Tokens get
487-
reused across multiple resource servers. It is not unimaginable that a custom claim is added to the
488-
Access Token on instantiation. This addition may unintentionally give other resource servers
489-
consuming the Access Token information about the user that they may not wish to share outside of the
490-
intended RS.
478+
With JWTs being extendable by design, there is potential for a privacy breach if OIDC ID Tokens get
479+
reused across multiple authorization servers. It is not unimaginable that a custom claim is added to the
480+
OIDC ID Token on instantiation. This addition may unintentionally give other authorization servers
481+
consuming the OIDC ID Token information about the user that they may not wish to share outside of the
482+
intended AS.
491483

492484
# Acknowledgments # {#acknowledgments}
493485

@@ -562,6 +554,16 @@ Verborgh, Ricky White, Paul Worrall, Dmitri Zagidulin.
562554
"title": "Solid Protocol",
563555
"publisher": "W3C Solid Community Group"
564556
},
557+
"Solid.OIDC.Primer": {
558+
"authors": [
559+
"Jackson Morgan",
560+
"Aaron Coburn",
561+
"Matthieu Bosquet"
562+
],
563+
"href": "https://solid.github.io/solid-oidc/primer/",
564+
"title": "Solid-OIDC Primer",
565+
"publisher": "W3C Solid Community Group"
566+
},
565567
"WebID": {
566568
"authors": [
567569
"Andrei Sambra",
@@ -571,6 +573,16 @@ Verborgh, Ricky White, Paul Worrall, Dmitri Zagidulin.
571573
"href": "https://www.w3.org/2005/Incubator/webid/spec/identity/",
572574
"title": "WebID 1.0",
573575
"publisher": "WebID Incubator Group"
576+
},
577+
"UMA": {
578+
"authors": [
579+
"Eve Maler",
580+
"Maciej Machulak",
581+
"Justin Richer"
582+
],
583+
"href": "https://docs.kantarainitiative.org/uma/wg/rec-oauth-uma-grant-2.0.html",
584+
"title": "User-Managed Access (UMA) 2.0 Grant for OAuth 2.0 Authorization",
585+
"publisher": "Kantara Initiative, Inc"
574586
}
575587
}
576588
</pre>

0 commit comments

Comments
 (0)