Skip to content
This repository was archived by the owner on Apr 13, 2022. It is now read-only.

Commit 06c3726

Browse files
jaxoncreeddmitrizagidulin
authored andcommitted
Fix typos and add more steps
1 parent 86480d8 commit 06c3726

File tree

2 files changed

+72
-25
lines changed

2 files changed

+72
-25
lines changed

ApplicationWorkflow.png

9.03 KB
Loading

application-workflow-detailed.md

Lines changed: 72 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
# Detailed Application Authentication
1+
# Detailed Web Application Authentication
22

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`.
44

55
## Actors
66

77
In this example a multitude of actors are at play:
88

99
**Alice** - Alice will be providing consent for decentphotos to use her pod. Let's assume that Alice is using a standard web browser.
1010

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`.
1212

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`.
1414

1515
**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`.
1616

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).
1818

1919
## Application Flow
2020

@@ -24,26 +24,65 @@ In this example a multitude of actors are at play:
2424

2525
Before any requests can be made, Alice must log in:
2626

27-
#### 1. Alice naviages to www.decentphotos.example
27+
#### 1. Alice navigates to www.decentphotos.example
2828

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.
3030

3131
#### 2. Alice clicks the "Connect" button
3232

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`)
3434

3535
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`.
3636

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:
42+
43+
```bash
44+
OPTIONS https://alice.coolpod.example/profile/card#me
45+
```
3846

39-
Now that Alice has indicated either her webId or her OP's url, the RP must make a request to retrieve the OP's configuration.
47+
The Pod may return a link header similar to this:
4048

41-
If Alice entered her webId the request would be her webId's origin plus a path for the OIDC configuration:
4249
```bash
43-
GET https://alice.coolpod.example/.well-known/openid-configuration
50+
RESPONSE HEADERS:
51+
Link: <https://secureauth.example>; rel="http://openid.net/specs/connect/1.0/issuer", <card.acl>; rel="acl", <card.meta>; rel="describedBy", <http://www.w3.org/ns/ldp#Resource>; rel="type"
52+
```
53+
54+
The attribute labeled by "http://openid.net/specs/connect/1.0/issuer" is the OP.
55+
56+
If the issuer is not in the Link header, make a `GET` request to the Pod.
57+
58+
```bash
59+
GET https://alice.coolpod.example/profile/card#me
60+
```
61+
62+
It will return a bod similar to this:
63+
64+
```
65+
@prefix : <#>.
66+
@prefix solid: <http://www.w3.org/ns/solid/terms#>.
67+
@prefix foaf: <http://xmlns.com/foaf/0.1/>.
68+
@prefix schema: <http://schema.org/>.
69+
70+
<>
71+
a foaf:PersonalProfileDocument ;
72+
foaf:maker <https://localhost:8443/profile/card#me> ;
73+
foaf:primaryTopic <https://localhost:8443/profile/card#me> .
74+
75+
:me a foaf:Person ;
76+
a schema:Person ;
77+
foaf:name "Alice" ;
78+
solid:oidcIssuer <https://secureauth.example> ;
4479
```
4580

46-
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`
4786

4887
```
4988
GET https://secureauth.example/.well-known/openid-configuration
@@ -124,7 +163,7 @@ OPENID_CONFIGURATION
124163

125164
#### 5. Generates a Private/Public key pair
126165

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.
128167

129168
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:
130169

@@ -235,8 +274,8 @@ Each of these communicates something about the new client to the OP:
235274
- `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.
236275
- `issuer`: Alice's OP
237276
- `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`
240279

241280
#### 10: Saves Client Information
242281

@@ -284,15 +323,15 @@ CLIENT_REGISTRATION_RESPONSE
284323

285324
#### 12. Authorization Request
286325

287-
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.
288327

289328
```
290329
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
291330
```
292331

293332
That url might look a little complex, but it's essentially a request to `https://secureauth.example/authorize` with the following url parameters:
294333

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.
296335
- `client_id=7243fd594bdcf9c71a9b902274afaa30`: indicates the id of the client. The value for this field should be obtained in the registration phase.
297336
- `response_type=id_token%20token` indicates the desired response data. Note that you cannot use response types that were not previously indicated during registration.
298337
- `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:/
321360

322361
#### 13. Gets Alice's Consent
323362

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.
325364

326365
#### 14. Generates an id_token
327366

@@ -385,7 +424,7 @@ ID_TOKEN
385424

386425
#### 1. Wraps id_token in pop_token
387426

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.
389428

390429
When decrypted, a pop_token can look like
391430

@@ -400,7 +439,7 @@ When decrypted, a pop_token can look like
400439
}
401440
```
402441

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.
404443

405444
#### 2. Request sent
406445

@@ -420,9 +459,17 @@ When a RS receives a pop_token it should first to see if the audience refers to
420459

421460
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.
422461

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
424471

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.
426473

427474
```
428475
GET https://secureauth.example/.well-known/openid-configuration
@@ -433,10 +480,10 @@ GET https://secureauth.example/jwks
433480

434481
In order to decrease network usage, RSs SHOULD cache these keys once received and skip this step given keys are already in the cache.
435482

436-
#### 6. Performs Authentication
483+
#### 8. Performs Authentication
437484

438485
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.
439486

440-
#### 7. Returns Result
487+
#### 9. Returns Result
441488

442489
Given all went well, the RS should return the requested content.

0 commit comments

Comments
 (0)