Skip to content

Commit a607894

Browse files
authored
Merge pull request #80 from cslzchen/feature/eng-2996-oauth-guide
[ENG-2996] Add OAuth SSO guide
2 parents 19834be + 7f2993d commit a607894

File tree

1 file changed

+286
-0
lines changed

1 file changed

+286
-0
lines changed

README_OAUTH_SSO_GUIDE.md

Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
1+
# OSF CAS as an OAuth Server
2+
3+
## About
4+
5+
OSF CAS serves as an OAuth 2.0 authorization server for OSF in addition to its primary role as a CAS authentication server.
6+
7+
### The OAuth 2.0 Protocol
8+
9+
* [RFC 6749](https://tools.ietf.org/html/rfc6749)
10+
* [OAuth 2.0](https://oauth.net/2/)
11+
* [OAuth 2.0 Simplified](https://aaronparecki.com/oauth-2-simplified/)
12+
13+
### Parties
14+
15+
| Party | Who |
16+
|----------------------|-------------------|
17+
| Client Application | A web application |
18+
| Authorization Server | OSF CAS |
19+
| Resource Owner | OSF Users |
20+
| Resource Server | OSF API |
21+
22+
## Features
23+
24+
### General
25+
26+
* Authorize client applications
27+
* Exchange authorization code for access and refresh token
28+
* Refresh access token using refresh token
29+
* Revoke access and refresh tokens
30+
31+
### Client Application Owners
32+
33+
* Revoke all tokens of the application for all users
34+
35+
### Resource Owners
36+
37+
* List all authorized applications
38+
* Revoke all tokens of an authorized application for the owner
39+
40+
<br>
41+
42+
## Endpoints
43+
44+
### `GET /oauth2/authorize`
45+
46+
#### Authorize a Client Application
47+
48+
Securely allows or denies the client application's request to access the resource user's information with specified scopes. It returns a one-time and short-lived authorization code, which will be used to follow up with the token-code exchange.
49+
50+
* Authorization Web Flow
51+
* (1) The client application issues the initial authorization request to `oauth2/authorize` with the above parameters;
52+
* (2) If the user is not logged in, redirects to the primary CAS login with `oauth2/callbackAuthorize` as service;
53+
* (3) Both step 1 and 2 end up redirecting the user to `oauth2/callbackAuthorize` for service validation;
54+
* (4) After validation, redirects to `oauth2/callbackAuthorize` one more time, which checks previous decisions and asks the user to allow or deny the authorization if necessary.
55+
* (5) If denied, redirects to `/oauth2/callbackAuthorizeAction?action=DENY`; if allowed, redirects to `/oauth2/callbackAuthorizeAction?action=ALLOW`
56+
* (6) Finally, for both decisions in step 5, redirects the user to the *Redirect URI*: `https://my.app.io/oauth2/callback?` with different query parameters as shown below.
57+
58+
* Request in Step (1)
59+
60+
```
61+
https://accounts.osf.io/oauth2/authorize
62+
```
63+
64+
| Parameter | Value / Example | Notes |
65+
|-----------------|-------------------------------------|--------------------------------|
66+
| response_type | code | |
67+
| client_id | `ffe5247b810045a8a9277d3b3b4edc7a` | |
68+
| redirect_uri | `https://my.app.io/oauth2/callback` | |
69+
| scope | `osf.full_read` | |
70+
| access_type | **`online`** / `offline` | Optional with default `online` |
71+
| approval_prompt | **`auto`** / `force` | Optional with default `auto` |
72+
73+
* Response in Step (6)
74+
75+
| Parameter | Value / Example | Note |
76+
|-----------|-----------------------------------------------------------|------------------------|
77+
| code | `AC-1-mFs7MrWvaQy1fiidWGwXTw4dbAH30wk39cAELJnxizjGCUXYJl` | If `ALLOW` in step (5) |
78+
79+
| Parameter | Value / Example | Note |
80+
|-----------|-----------------|-----------------------|
81+
| error | `access_denied` | If `DENY` in step (5) |
82+
83+
<br><hr>
84+
85+
### `POST /oauth2/token`
86+
87+
#### Exchange Code for Token
88+
89+
Exchanges the authorization code for an access token and potentially a refresh token if `offline` mode was specified **when requesting for the authorization code**.
90+
91+
* Request
92+
93+
```
94+
https://accounts.osf.io/oauth2/token
95+
```
96+
97+
* `POST` Body Parameters
98+
99+
| Parameter | Value / Example | Notes |
100+
|---------------|-----------------------------------------------------------|-------|
101+
| code | `AC-1-mFs7MrWvaQy1fiidWGwXTw4dbAH30wk39cAELJnxizjGCUXYJl` | |
102+
| client_id | `ffe5247b810045a8a9277d3b3b4edc7a` | |
103+
| client_secret | `5PgE96R3Z53dBuwBDkJfbK6ItDXvGhaxYpQ6r4cU` | |
104+
| redirect_uri | `https://my.app.io/oauth2/callback` | |
105+
| grant_type | `authorization_code` | |
106+
107+
* Response Status
108+
109+
```
110+
HTTP 200 OK
111+
```
112+
* Response Body if `online` Mode
113+
114+
```json
115+
{
116+
"access_token": "AT-2-p5jtVLATgft5EHqqbCTagg5i3q9e1htdcGEBvcpq0l1b2RyQav4bItEKPcDh94c5z7d7EK",
117+
"token_type": "Bearer",
118+
"expires_in": 3600
119+
}
120+
```
121+
122+
* Response Body if `offline` Mode
123+
124+
```json
125+
{
126+
"access_token": "AT-1-IBGuzWBdencAMz74LQkIuNcbLuu9WM3TYyacadkecrHUlcivs1GnWHjFmlkZPYg4TTAUM4",
127+
"refresh_token": "RT-1-xfQXZaqXSQIJykCg2vnfdQjc5efVKdtteXaPo0OwCxWzIAacfC",
128+
"token_type": "Bearer",
129+
"expires_in": 3600
130+
}
131+
```
132+
133+
#### Refresh Access Token
134+
135+
In *`offline`* mode, the client application may request for a new access token by presenting the previously granted refresh token.
136+
137+
* Request
138+
139+
```
140+
https://accounts.osf.io/oauth2/token
141+
```
142+
143+
* `POST` Body Parameters
144+
145+
| Parameter | Value / Example | Note |
146+
|---------------|-----------------------------------------------------------|------|
147+
| refresh_token | `RT-1-xfQXZaqXSQIJykCg2vnfdQjc5efVKdtteXaPo0OwCxWzIAacfC` | |
148+
| client_id | `ffe5247b810045a8a9277d3b3b4edc7a` | |
149+
| client_secret | `5PgE96R3Z53dBuwBDkJfbK6ItDXvGhaxYpQ6r4cU` | |
150+
| grant_type | `refresh_token` | |
151+
152+
* Response Status
153+
154+
```
155+
HTTP 200 OK
156+
```
157+
158+
* Response Body
159+
160+
```json
161+
{
162+
"access_token": "AT-3-WbBmXVTsPlhUatrs5sQmilVLnA30wVv3holmfFCbIfePRjzQ6UXCb7LwJHGbFqmad3wNXu",
163+
"token_type": "Bearer",
164+
"expires_in": 3600
165+
}
166+
```
167+
168+
<br><hr>
169+
170+
### `GET /oauth2/profile`
171+
172+
#### Profile
173+
174+
Provides the user's principal ID, any released attributes and a list of granted scopes.
175+
176+
* Request
177+
178+
```
179+
https://accounts.osf.io/oauth2/profile
180+
```
181+
182+
* Authorization Header
183+
184+
| Name | Value / Example | Note |
185+
|---------------|--------------------------------------------------------------------------------------|------|
186+
| Authorization | `Bearer AT-4-IdanI4hWiybRzARBiLrlMdeMTlDJIqo1UgVLb4MHzbF13pNIT5POrfQTMW5yEyVD1oXXcz` | |
187+
188+
* Response Status
189+
190+
```
191+
HTTP 200 OK
192+
```
193+
194+
* Response Body
195+
196+
```json
197+
{
198+
"scope": [
199+
"osf.full_read"
200+
],
201+
"id": "f2t7d"
202+
}
203+
```
204+
205+
<br><hr>
206+
207+
### `POST /oauth2/revoke`
208+
209+
#### Revoke One Token
210+
211+
Handles revocation of refresh and access tokens.
212+
213+
* Request: Revoke one access token
214+
215+
```
216+
https://accounts.osf.io/oauth2/revoke
217+
```
218+
219+
* `POST` Body Parameters for revoke one access token
220+
221+
| Name | Value / Example | Note |
222+
|-------|-------------------------------------------------------------------------------|------|
223+
| token | `AT-6-0ckMxjkBHgs5PMqbCtg9BgFo49Y60A1bC5QxFnQeWdiWe9ZfvKwWS52jyIwLrrwVMGFxfa` | |
224+
225+
* `POST` Body Parameters for revoke one refresh token and all access token granted by this refresh token.
226+
227+
| Name | Value / Example | Note |
228+
|-------|-----------------------------------------------------------|------|
229+
| token | `RT-1-xfQXZaqXSQIJykCg2vnfdQjc5efVKdtteXaPo0OwCxWzIAacfC` | |
230+
231+
* Response Status
232+
233+
```
234+
HTTP 204 NO CONTENT
235+
```
236+
237+
#### Revoke Tokens for a Client Application
238+
239+
Revokes all tokens associated with a client application specified by the given client ID.
240+
241+
* Request
242+
243+
```
244+
https://accounts.osf.io/oauth2/revoke
245+
```
246+
247+
* `POST` Body Parameters
248+
249+
| Parameter | Value / Example | Note |
250+
|---------------|--------------------------------------------|------|
251+
| client_id | `ffe5247b810045a8a9277d3b3b4edc7a` | |
252+
| client_secret | `5PgE96R3Z53dBuwBDkJfbK6ItDXvGhaxYpQ6r4cU` | |
253+
254+
* Response Status
255+
256+
```
257+
HTTP 204 NO CONTENT
258+
```
259+
260+
#### Revoke All Tokens for a Resource User
261+
262+
Revokes all tokens of a client application that have been issued to a resource user. The application is specified by the client ID and the user is specified by the principal ID associated with the access token. The token used for authorization must have been generated by the application *unless it is of token type `CAS`*.
263+
264+
* Request
265+
266+
```
267+
https://accounts.osf.io/oauth2/revoke
268+
```
269+
270+
* Authorization Header
271+
272+
| Name | Value / Example | Note |
273+
|---------------|--------------------------------------------------------------------------------------|------|
274+
| Authorization | `Bearer AT-7-PvVw9wIcTOZYXFCVWbFhwsf9Q3idASiJeBdiWmLExcXSG54lCycokgCefWsy2Nzds4LoAW` | |
275+
276+
* `POST` Body Parameters
277+
278+
| Parameter | Value / Example | Note |
279+
|-----------|------------------------------------|------|
280+
| client_id | `ffe5247b810045a8a9277d3b3b4edc7a` | |
281+
282+
* Response Status
283+
284+
```
285+
HTTP 204 NO CONTENT
286+
```

0 commit comments

Comments
 (0)