|
2 | 2 |
|
3 | 3 | Use this project to delegate authentication to an external OpenID Connect provider (OP) using the *authorization code flow*.
|
4 | 4 |
|
5 |
| -## How it works at a glance |
| 5 | +## Anatomy |
6 | 6 |
|
7 |
| -When the main flow of this project is launched (namely, `io.jans.inbound.openid`) the user's browser is redirected to the authorization page of the configured OP. There authentication takes place and subsequently an access token is obtained to grab user profile data. A user entry is inserted in the local Jans database and a session is created for such "local" user in the Jans Authorization Server. Finally the user's browser is taken to the registered redirect URI. |
| 7 | +The project consists of three flows that provide incremental functionality: |
8 | 8 |
|
9 |
| -## Requirements |
| 9 | +- `org.gluu.inbound.oauth2.AuthzCode`: With this flow the user's browser is redirected to the authorization page of an external OP (the specifics are passed in the input parameters). Authentication takes place there and subsequently an access token is obtained and returned to the caller of the flow |
10 | 10 |
|
11 |
| -### Enabled Agama |
| 11 | +- `org.gluu.inbound.oauth2.AuthzCodeWithUserInfo`: This flow launches `AuthzCode` and then obtains the profile data of the authenticated user by presenting an access token. Both the token and profile data are returned to the caller |
12 | 12 |
|
13 |
| -Ensure Agama is [enabled](https://docs.jans.io/head/admin/developer/agama/engine-bridge-config/#availability) in your Jans Server. |
| 13 | +- `org.gluu.inbound.openid`: This flow launches `AuthzCodeWithUserInfo` and inserts an entry in the local Jans database for the user in question. Depending on how the flow is parameterized, this flow can perform a preliminar OpenID client registration |
14 | 14 |
|
15 |
| -### External OP settings |
| 15 | +## `openid` flow |
16 | 16 |
|
17 |
| -Obtain the following from the OP you want to support: |
| 17 | +Most of times, this is the flow that developers will want to reuse in their projects. It receives two input parameters: |
18 | 18 |
|
19 |
| -- The authorization endpoint URL |
20 |
| -- The token endpoint URL |
21 |
| -- The userinfo endpoint |
22 |
| -- The scopes required to obtain user data |
23 |
| -- Client credentials (client ID and secret) |
| 19 | +- `opSettings`. An Agama map that specify the settings to be able to interact with the external OP |
| 20 | +- `uidPrefix`. A string value used for user provisioning: the user inserted in local DB will have an `uid` equal to the concatenation of `uidPrefix` and the `sub` released by the external OP. This param can be omitted or set to `null` if no prefixing is desired |
24 | 21 |
|
25 |
| -In this process, you will be required to supplied a redirect URI, use the following: `https://<jans-server-host-name>/jans-auth/fl/callback` |
| 22 | +### OP settings |
26 | 23 |
|
27 |
| -## Project deployment |
| 24 | +The structure of `opSettings` is as follows: |
28 | 25 |
|
29 |
| -- Copy (SCP/SFTP) the gama file of this project to a location in your Jans server |
30 |
| -- Connect (SSH) to your Jans Server and open TUI: `python3 /opt/jans/jans-cli/jans_cli_tui.py` |
31 |
| -- Navigate to the Agama tab and then select "Upload project". Choose the gama file |
32 |
| -- Wait for about one minute and then select the row in the table corresponding to this project |
33 |
| -- Press `d` and ensure there were not deployment errors |
34 |
| -- Pres ESC to close the dialog |
| 26 | +|Name|Description|Notes| |
| 27 | +|-|-|-| |
| 28 | +|`host`|Location of the identity provider, eg. `https://my.idp.co`|Required if DCR is enabled, see below| |
| 29 | +|`dcr`|The `openid` flow can make use of Dynamic Client Registration (DCR) - a feature some OPs provide|Required| |
| 30 | +|`oauth`|A map following the same structure of [oauthParams](#authzcodewithuserinfo-and-authzcode)|| |
35 | 31 |
|
36 |
| -## Project configuration |
| 32 | +Regarding oauth map, **not all fields** marked as required are necessary when DCR is enabled. It suffices to supply `scopes`. |
37 | 33 |
|
38 |
| -- Still with the row highlighted, press `c` and choose to export the sample configuration to a file |
39 |
| -- Edit a copy of the file according to the OP settings formerly grabbed. They should go under the `io.jans.inbound.openid` section |
40 |
| -- Still with the row highlighted, press `c` and choose to import configuration. Supply the file just edited |
| 34 | +Here is a minimalistic value that can be supplied for `opSettings` when DCR is supported by the external OP: |
41 | 35 |
|
42 |
| -## Testing |
| 36 | +``` |
| 37 | +{ |
| 38 | + host: "https://my.idp.co", |
| 39 | + dcr: { enabled: true, useCachedClient: true }, |
| 40 | + oauth: { scopes: [ "openid" ] } |
| 41 | +} |
| 42 | +``` |
43 | 43 |
|
44 |
| -Configure the required in your Jans Server to be able to launch an authentication flow. Actual details may vary but you can resort to a handy browser extension called [jans-tarp](https://github.com/JanssenProject/jans/tree/main/demos/jans-tarp) that will save you a good amount of work. |
| 44 | +### DCR settings |
45 | 45 |
|
46 |
| -When testing ensure the following parameters are present in the authorization request: |
| 46 | +The structure of `dcr` is as follows: |
| 47 | + |
| 48 | +|Name|Description|Notes| |
| 49 | +|-|-|-| |
| 50 | +|`enabled`|A boolean value indicating if DCR will be used for the external OP|Required<!--Optional. `false` value assumed if missing-->| |
| 51 | +|`useCachedClient`|Once the first client registration takes place, no more registration attempts will be made until the client is about to expire. Set this to `true` to force registration every time `openid` flow is launched|Required| |
| 52 | + |
| 53 | + |
| 54 | +## `AuthzCodeWithUserInfo` and `AuthzCode` |
| 55 | + |
| 56 | +Each of these flows receive an input parameter (`oauthParams`) to drive their behavior. `oauthParams` is expected to be an Agama map with the following structure: |
| 57 | + |
| 58 | +|Name|Description|Notes| |
| 59 | +|-|-|-| |
| 60 | +|`authzEndpoint`|The authorization endpoint as in section 3.1 of [RFC 7649](https://www.ietf.org/rfc/rfc6749)|Required| |
| 61 | +|`tokenEndpoint`|The token endpoint as in section 3.2 of [RFC 7649](https://www.ietf.org/rfc/rfc6749)|Required| |
| 62 | +|`userInfoEndpoint`|The endpoint where profile data can be retrieved. This is not part of the OAuth2 specification|Optional| |
| 63 | +|`clientId`|The identifier of the client to use, see section 1.1 and 2.2 of [RFC7649](https://www.ietf.org/rfc/rfc6749). This client is assumed to be *confidential* as in section 2.1|Required| |
| 64 | +|`clientSecret`|Secret associated to the client|Required| |
| 65 | +|`scopes`|An array of strings that represent the scopes of the access tokens to retrieve|Required| |
| 66 | +|`redirectUri`|Redirect URI as in section 3.1.2 of [RFC 7649](https://www.ietf.org/rfc/rfc6749)|Optional (auto filled when missing)| |
| 67 | +|`clientCredsInRequestBody`|`true` indicates the client authenticates at the token endpoint by including the credentials in the body of the request, otherwise, HTTP Basic authentication is assumed. See section 2.3.1 of [RFC 7649](https://www.ietf.org/rfc/rfc6749)|Optional. `false` is assumed if not supplied| |
| 68 | +|`custParamsAuthReq`|An Agama map (keys and values expected to be strings) with extra parameters to pass to the authorization endpoint if desired|Optional| |
| 69 | +|`custParamsTokenReq`|An Agama map (keys and values expected to be strings) with extra parameters to pass to the token endpoint if desired|Optional| |
| 70 | + |
| 71 | +## FAQ |
| 72 | + |
| 73 | + |
| 74 | +### I don't use DCR and I am asked to provide a redirect URI in order to get a client ID/Secret |
| 75 | + |
| 76 | +Supply the following: `https://<jans-server-host-name>/jans-auth/fl/callback` |
| 77 | + |
| 78 | +### What methods for token endpoint authentication are supported? |
| 79 | + |
| 80 | +Only `client_secret_basic` and `client_secret_post` are supported |
47 | 81 |
|
48 |
| -- `acr_values=agama` |
49 |
| -- `agama_flow=io.jans.inbound.openid` |
|
0 commit comments