You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Apr 13, 2022. It is now read-only.
Copy file name to clipboardExpand all lines: application-workflow-detailed.md
+72-25Lines changed: 72 additions & 25 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,20 +1,20 @@
1
-
# Detailed Application Authentication
1
+
# Detailed Web Application Authentication
2
2
3
-
This document outlines, in detail, the login and request process for an application using WebId-OIDC. In general, our user, *Alice* will be using a thrid-party application at `https://www.decentphotos.example` to access data on both her pod at `https://alice.example` and her friend, Bob's pod at `https://bob.example`.
3
+
This document outlines, in detail, the login and request process for an web application using WebId-OIDC. In general, our user, *Alice* will be using a third-party web application at `https://www.decentphotos.example` to access data on both her pod at `https://alice.example` and her friend, Bob's pod at `https://bob.example`.
4
4
5
5
## Actors
6
6
7
7
In this example a multitude of actors are at play:
8
8
9
9
**Alice** - Alice will be providing consent for decentphotos to use her pod. Let's assume that Alice is using a standard web browser.
10
10
11
-
**Bob's Pod (RS)** - We will be trying to access photos Bob's Pod, known in the OIDC world as a Resource Server (RS). Bob is a friend of Alice. For this use case, let's assume that Bob has previously indicated via access control that Alice may access his photo using any app. You can read more about access control [here](https://github.com/solid/web-access-control-spec#referring-to-origins-ie-web-apps). For this example, bob's pod is at `bob.solid.example`.
11
+
**Bob's Pod (RS)** - We will be trying to access photos stored in Bob's Pod, known in the OIDC world as a Resource Server (RS). Bob is a friend of Alice. For this use case, let's assume that Bob has previously indicated via access control that Alice may access his photo using any webapp. You can read more about access control [here](https://github.com/solid/web-access-control-spec#referring-to-origins-ie-web-apps). For this example, bob's pod is at `bob.solid.example`.
12
12
13
-
**Alice's OP** - Alice's OpenID Provider (OP), also known as an IDP (Identity Provider), is the service responsible for authorizing our thrid-party app by providing it with the tokens necessary to gain access to any pod. In this demo, alice's OP is at `secureauth.example`.
13
+
**Alice's OP** - Alice's OpenID Provider (OP), also known as an IDP (Identity Provider), is the service responsible for authorizing our third-party webapp by providing it with the tokens necessary to gain access to any pod. In this demo, alice's OP is at `secureauth.example`.
14
14
15
15
**Alice's Pod (RS)** - Alice's Pod is hosted at `alice.coolpod.example`, giving Alice the webId of `https://alice.coolpod.example/profile/card#me`.
16
16
17
-
**Decent Photos (RP)** - decentphotos is a third party photo viewing application hosted at `https://www.decentphotos.example`. This app allows you to view your photos as well as your friend's photos. It will also perform cron jobs on the photos to detect faces. In the OIDC world this is known as the Relying Party (RP).
17
+
**Decent Photos (RP)** - decentphotos is a third party photo viewing web application hosted at `https://www.decentphotos.example`. This webapp allows you to view your photos as well as your friend's photos. It will also perform cron jobs on the photos to detect faces. In the OIDC world this is known as the Relying Party (RP).
18
18
19
19
## Application Flow
20
20
@@ -24,26 +24,65 @@ In this example a multitude of actors are at play:
24
24
25
25
Before any requests can be made, Alice must log in:
26
26
27
-
#### 1. Alice naviages to www.decentphotos.example
27
+
#### 1. Alice navigates to www.decentphotos.example
28
28
29
-
Alice has heard of a great new site that allows her to view her friend's photos and tag faces. She navigates to `www.decentphotos.example` via he web browser which returns and html page. This page contains JavaScript that will help with the authentication process.
29
+
Alice has heard of a great new site that allows her to view her friend's photos and tag faces. She navigates to `www.decentphotos.example` via her web browser which returns an html page. This page contains JavaScript that will help with the authentication process.
30
30
31
31
#### 2. Alice clicks the "Connect" button
32
32
33
-
Before decentphotos can start displaying images, Alice needs to start the process of providing consent. To do so, she must either provider her webId (`https://alice.coolpod.example/profile/card#me`) or the service the url of her OP (`https://secureauth.example`)
33
+
Before decentphotos can start displaying images, Alice needs to start the process of providing consent. To do so, she must either provide her webId (`https://alice.coolpod.example/profile/card#me`) or the url of her OP (`https://secureauth.example`)
34
34
35
35
While it is not the case with Alice, a user's Pod and OP can be hosted at the same domain. For example, Bob's pod could be `bob.solid.example` with a webId of `https://bob.solid.example/profile/card#me`, but his OP is at `https://solid.example`.
36
36
37
-
#### 3. Request OP Configuration
37
+
##### 2.1. Retrieve Profile
38
+
39
+
If Alice entered her Pod's url rather than her OP's url, a request should be make to determine her OP. There are two ways to do this and Pods may support one or both of them:
40
+
41
+
Firstly, the RP should make an `OPTIONS` request to the Pod:
If Alice entered her OP's url, the RP would simply append the OIDC configuration to the end.
81
+
The OP url is located at `:me -> solid:oidcIssuer`
82
+
83
+
#### 3. Request OP Configuration
84
+
85
+
Now that we have Alice's OP's url, the RP must make a request to retrieve the OP's configuration. This is always located at the OP's host followed by `/.well-known/openid-configuration`
47
86
48
87
```
49
88
GET https://secureauth.example/.well-known/openid-configuration
@@ -124,7 +163,7 @@ OPENID_CONFIGURATION
124
163
125
164
#### 5. Generates a Private/Public key pair
126
165
127
-
WebId-OIDC depends on [Proof of Posession (PoP) tokens](README.md#securing-tokens-for-multiple-resource-servers). PoP tokens ensure that third-party applications can send requests to any number of Pods, while ensuring that evil pods can't steal a user's token.
166
+
WebId-OIDC depends on [Proof of Posession (PoP) tokens](README.md#securing-tokens-for-multiple-resource-servers). PoP tokens ensure that third-party web applications can send requests to any number of Pods, while ensuring that evil pods can't steal a user's token.
128
167
129
168
The first step to generating a PoP token is generating a public and private key pair on the third-party RP. In our example, the private key is generated using `RSA256` and looks like:
130
169
@@ -235,8 +274,8 @@ Each of these communicates something about the new client to the OP:
235
274
-`grant_types`: A list of [OIDC grant types](http://docs.identityserver.io/en/latest/topics/grant_types.html) this client will use. `implicit` is great for web applications.
236
275
-`issuer`: Alice's OP
237
276
-`redirect_uris`: Redirect uris provided at the client registration stage state which redirect uris are valid during the authorization stage.
238
-
-`response_types`: A list of [OIDC response types](https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html) the client can use. `id_token token` means that it should return both an Id Token (needed to identify this application later) and an access token.
239
-
-`scope`: OIDC uses scope as a way of defining what a client can have acces to. However, Solid has it's own access control system, so scope will always be `openid profile`
277
+
-`response_types`: A list of [OIDC response types](https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html) the client can use. `id_token token` means that it should return both an Id Token (needed to identify this web application later) and an access token.
278
+
-`scope`: OIDC uses scope as a way of defining what a client can have access to. However, Solid has its own access control system, so scope will always be `openid profile`
Now that the app is registered, we can finally make an auth request to authorize the application.
326
+
Now that the webapp is registered, we can finally make an auth request to authorize the web application.
288
327
289
328
```
290
329
GET https://secureauth.example/authorize?scope=openid&client_id=7243fd594bdcf9c71a9b902274afaa30&response_type=id_token%20token&redirect_uri=https%3A%2F%2Fwww.decentphotos.example%2F&request=eyJhbGciOiJub25lIn0.eyJyZWRpcmVjdF91cmkiOiJodHRwczovL2NoYXQuby50ZWFtLyIsImRpc3BsYXkiOiJwYWdlIiwibm9uY2UiOiJSWVRfUHFDMmpVMVNremoyTkViTjVFaUZFQ0szdTlad2dOcVlhVkl1RlFnIiwia2V5Ijp7ImFsZyI6IlJTMjU2IiwiZSI6IkFRQUIiLCJleHQiOnRydWUsImtleV9vcHMiOlsidmVyaWZ5Il0sImt0eSI6IlJTQSIsIm4iOiIyenltRTFQdDlPTm5saWpIMHlQN2ItZlUzZ0Vsb3liT3FNbVlKMHNTdFkxRU1DbzhUTXRLZkZtOXIwUnV6clRLMDJOX3VDNjZFcEdTaE9WeDJpMkRIMW1la1ZDeWV3a1pJM3BDZGVkUVk5dDhsY0VHUE5vcUVwSDViRkNZT2Jud3QtbHVUa0Q4N2hFX19MbWtrQV9wNG85MFZpREUwcEloYWxNaWt5SUsxNmZqV3I4dmFaeXRqbUVpUS04Z3k1SzZZSUpUdHJISXI4Yzd2dXprczJQeTlXb0xlOG8yVTBvaGFtRWd2QjhhbFJBUFFsUldiUHh3ZG5rVm85ZnI5UFBQelgzdHh4a2Q1NnN3andPZFJWalZwZmVoUVV0dDBuTHUwNDBjV3B2a1gwU1V4NnZMTklyYlExclM5UXkxMkdReGlqZDhfUjd1MFpIV1BoRkp3Y2hjancifX0.&state=L4F7Z7GrCu6cfxTh1qcEtCg1bfrs5daLhU5onmjeTS4
291
330
```
292
331
293
332
That url might look a little complex, but it's essentially a request to `https://secureauth.example/authorize` with the following url parameters:
294
333
295
-
-`scope=open_id`: a list of [oidc scpes](https://auth0.com/docs/scopes/current/oidc-scopes) (ways to communicate what the kind of information the authorization request should wants to get access to). `open_id` is a scope that is needed to verify Alice's identity.
334
+
-`scope=open_id`: a list of [oidc scpes](https://auth0.com/docs/scopes/current/oidc-scopes) (attributes of the RS to which this token should have access). `open_id` is a scope that is needed to verify Alice's identity.
296
335
-`client_id=7243fd594bdcf9c71a9b902274afaa30`: indicates the id of the client. The value for this field should be obtained in the registration phase.
297
336
-`response_type=id_token%20token` indicates the desired response data. Note that you cannot use response types that were not previously indicated during registration.
298
337
-`request=eyJhbGciOiJub25lIn0.eyJyZWRpc...`: A JWT containing the public key of the client and signed by the client using the private key. This is unique to webId-oidc. We will eventually use this to generate our pop-token.
@@ -321,7 +360,7 @@ That url might look a little complex, but it's essentially a request to `https:/
321
360
322
361
#### 13. Gets Alice's Consent
323
362
324
-
Given everything checks out in the last step, the OP should redirect to it's login screen. The actual implementation of this is completely up to the OP. A user can log in with her password, a TLS certificate, or any other proven method of authentication. The important thing is that, thanks to the redirect, the control is now out of the hands of the RP and is in complete control of the OP.
363
+
Given everything checks out in the last step, the OP should redirect to its login screen. The actual implementation of this is completely up to the OP. A user can log in with her password, a TLS certificate, or any other proven method of authentication. The important thing is that, thanks to the redirect, the control is now out of the hands of the RP and is in complete control of the OP.
325
364
326
365
#### 14. Generates an id_token
327
366
@@ -385,7 +424,7 @@ ID_TOKEN
385
424
386
425
#### 1. Wraps id_token in pop_token
387
426
388
-
A Solid application could need to talk to any number of Resource Servers. Because of this, we do not want a single token that's used to talk to all of them. A malicious resource server could steal that token and pretend to be the app. Instead, we wrap the id_token we've received from the OP in another token signed by the app. This is called a pop_token.
427
+
A Solid web application could need to talk to any number of Resource Servers. Because of this, we do not want a single token that's used to talk to all of them. A malicious resource server could steal that token and pretend to be the webapp. Instead, we wrap the id_token we've received from the OP in another token signed by the webapp. This is called a pop_token.
389
428
390
429
When decrypted, a pop_token can look like
391
430
@@ -400,7 +439,7 @@ When decrypted, a pop_token can look like
400
439
}
401
440
```
402
441
403
-
Notice this in this new token, the app is now the issuer and the audience is the specific serer to which we are sending a request. The id_token field contains the same token that we've saved to local storage.
442
+
Notice this in this new token, the web app is now the issuer and the audience is the specific serer to which we are sending a request. The id_token field contains the same token that we've saved to local storage.
404
443
405
444
#### 2. Request sent
406
445
@@ -420,9 +459,17 @@ When a RS receives a pop_token it should first to see if the audience refers to
420
459
421
460
The RS wants to ensure that this pop_token truely came from the client that the OP said it should come from when it signed the id_token. To do so, the RS should ensure that the public key included in the `cnf` field of the id_token matches the signature of the pop_token. If they do not match the RS MUST reject the request with a 403.
422
461
423
-
#### 5. Requests public keys
462
+
#### 5. Retrieves Profile
463
+
464
+
A request should be made to url in the `sub` field of the id_token (The user's Pod) to determine that user's OP via the issuer attribute. For instructions on this see step 2.1 of the authorization instructions.
465
+
466
+
#### 6. Checks Issuer
467
+
468
+
Compare the issuer retrieved in step 5 with the issuer of the id token. If they are not identical the RS must reject the request with a 403.
469
+
470
+
#### 7. Requests public keys
424
471
425
-
Now that we've confirmed the validity of the pop_token, we want to ensure the validity of the id_token it contains. To do so, we need the OP's public keys. The OP's address can be obtained via the `iss` field of the id_token (https://secureauth.example). Recall how to retrieve the OP's public keys in steps 3, 4, 7, and 8 of the authorization instructions.
472
+
Now that we've confirmed the validity of the pop_token and the subject of the identity token, we want to ensure the validity of the id_token it contains. To do so, we need the OP's public keys. The OP's address can be obtained via the `iss` field of the id_token (https://secureauth.example). Recall how to retrieve the OP's public keys in steps 3, 4, 7, and 8 of the authorization instructions.
426
473
427
474
```
428
475
GET https://secureauth.example/.well-known/openid-configuration
@@ -433,10 +480,10 @@ GET https://secureauth.example/jwks
433
480
434
481
In order to decrease network usage, RSs SHOULD cache these keys once received and skip this step given keys are already in the cache.
435
482
436
-
#### 6. Performs Authentication
483
+
#### 8. Performs Authentication
437
484
438
485
With OP public keys obtained, the RS can confirm if the id_token was signed by the OP. If it was not, the RS must reject the request with a 403.
439
486
440
-
#### 7. Returns Result
487
+
#### 9. Returns Result
441
488
442
489
Given all went well, the RS should return the requested content.
0 commit comments