Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(agama): add sample flows for inbound identity #2284

Merged
merged 2 commits into from
Aug 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/admin/developer/agama/samples.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Source code [here](https://github.com/JanssenProject/jans/raw/main/docs/admin/de

### UI template

[`login.ftlh`](https://github.com/JanssenProject/jans/raw/main/docs/admin/developer/agama/basic/login.ftlh) is 99% HTML markup and will not be detailed here. There are only a couple of things to highlight:
[`login.ftlh`](https://github.com/JanssenProject/jans/raw/main/docs/admin/developer/agama/basic/login.ftlh) is 99% HTML markup and will not be detailed here. There are only a couple of things to highlight:

- The conditional `<#if !(success!true)>` (around line 27) is used to determine if an error message should be included in the generated markup. It works this way: if the key `success` exists in this template data model, its value is negated (note the bang character before the left parenthesis) and the `if` condition is evaluated. If non-existing, a `true` value is assumed which is then negated and thus the `if` body will not be evaluated-

Expand Down
29 changes: 19 additions & 10 deletions docs/script-catalog/agama/inboundID/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ Note the scope here is limited: no session is created in the Janssen server for

To facilitate administrators' work, the following flows are already implemented:

- Apple
- [Facebook](https://github.com/JanssenProject/jans/tree/main/docs/script-catalog/agama/inboundID/facebook)
- [Github](https://github.com/JanssenProject/jans/tree/main/docs/script-catalog/agama/inboundID/github)
- [Google](https://github.com/JanssenProject/jans/tree/main/docs/script-catalog/agama/inboundID/google)
- [Apple](./apple/README.md)
- [Facebook](./facebook)
- [Github](./github)
- [Google](./google)

### Main flow

Expand Down Expand Up @@ -71,19 +71,28 @@ To start, let's add the required libraries to the authentication server:
- Navigate to `/opt/jans/jetty/jans-auth/webapps` and edit the file `jans-auth.xml` by adding `<Set name="extraClasspath">./custom/libs/*</Set>` before the root tag closes
- Restart the server, e.g. `systemctl restart jans-auth`

### Add the main inbound flow
### Add the basic authentication flow

The basic authentication flow is employed when no provider is picked from the list (step 1 [here](#main-flow)) but the option to use an existing local account is taken. This flow is detailed in the Agama sample flows [page](https://jans.io/docs/admin/developer/agama/samples/#basic-authentication), however those contents can be skipped for the purpose of this setup.

- Ensure Agama engine is [enabled](https://jans.io/docs/admin/developer/agama/quick-start/#enable-the-engine). Download the flow [source](https://github.com/JanssenProject/jans/raw/main/docs/script-catalog/agama/inboundID/io.jans.inbound.ExternalSiteLogin) file
- Ensure Agama engine is [enabled](https://jans.io/docs/admin/developer/agama/quick-start/#enable-the-engine). Download the basic flow [source](https://github.com/JanssenProject/jans/raw/main/docs/admin/developer/agama/basic/io.jans.flow.sample.basic) file

- Use the API for adding flows as explained [here](https://jans.io/docs/admin/developer/agama/quick-start/#getting-an-access-token) and [here](https://jans.io/docs/admin/developer/agama/quick-start/#add-the-flow-to-the-server). A sample `curl` command would look like this:

```
curl -k -i -H 'Authorization: Bearer <token>' -H 'Content-Type: text/plain'
--data-binary @io.jans.inbound.ExternalSiteLogin
https://<your-host>/jans-config-api/api/v1/agama/io.jans.inbound.ExternalSiteLogin
--data-binary @io.jans.flow.sample.basic
https://<your-host>/jans-config-api/api/v1/agama/io.jans.flow.sample.basic
```
- In the server, navigate to `/opt/jans/jetty/jans-auth/agama/ftl`. Create the folder hierarchy `samples/basic` there

- Download the login [template](https://github.com/JanssenProject/jans/raw/main/docs/admin/developer/agama/basic/login.ftlh) to `basic` directory

### Add the main inbound flow

- Download the flow [source](https://github.com/JanssenProject/jans/raw/main/docs/script-catalog/agama/inboundID/io.jans.inbound.ExternalSiteLogin) and add it as you did with the basic flow, ensure you use `io.jans.inbound.ExternalSiteLogin` this time

- In the server, navigate to `/opt/jans/jetty/jans-auth/agama/`. Create folders named `inboundID` inside existing `ftl` and `fl` subdirectories
- In the server, navigate to `/opt/jans/jetty/jans-auth/agama`. Create folders named `inboundID` inside existing `ftl` and `fl` subdirectories

- Download the default [logo](https://github.com/JanssenProject/jans/raw/main/docs/script-catalog/agama/inboundID/none.png) and place it inside `/opt/jans/jetty/jans-auth/agama/fl/inboundID` folder

Expand Down Expand Up @@ -216,7 +225,7 @@ The table below explains the meaning of properties:

### Provider flow configurations

Configurations for this kind of flows don't have to adhere to any specific structure. Developers are free to choose what fits best for their needs. Also note provider flows **must not** receive any inputs: the main flow won't pass any arguments when triggering them. Thus, design your flows so there is no use of `Inputs` but `Configs` directive in the [header](https://jans.io/docs/admin/developer/agama/dsl-full/#header-basics) .
Configurations for this kind of flows don't have to adhere to any specific structure. Developers are free to choose what fits best for their needs. Also note provider flows **must not** receive any inputs: the main flow won't pass any arguments when triggering them. Thus, design your flows so there is no use of `Inputs` but `Configs` directive in the [header](https://jans.io/docs/admin/developer/agama/dsl-full/#header-basics).

In practice many identity providers adhere to the OAuth2 `code` grant, so you can re-use the structure represented by [this](https://github.com/JanssenProject/jans/blob/main/agama/inboundID/src/main/java/io/jans/inbound/oauth2/OAuthParams.java) Java class for the purpose. Particularly, the already implemented flows (like Facebook) use it for their configuration.

Expand Down
74 changes: 74 additions & 0 deletions docs/script-catalog/agama/inboundID/apple/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# The "Sign In With Apple" Agama flow

To deploy this flow, a number of configurations are required. Ensure you have an Apple developer account to start. [This tutorial](https://github.com/ananay/apple-auth/blob/master/SETUP.md) does a great job at explaining the necessary steps. As you go with it, ensure you collect the following elements:

- A service ID
- A team ID
- A key ID and a key file

You will be prompted to provide a domain name and a return URL. Provide `<your-jans-host>` and `https://<your-jans-host>/jans-auth/fl/callback` respectively, ensuring the changes are effectively saved in the developer's portal.

Please follow the [inbound identity guide](../README.md) **entirely** before proceeding.

## Flow and assets

Find this flow source code [here](https://github.com/JanssenProject/jans/raw/main/docs/script-catalog/agama/inboundID/apple/io.jans.inbound.Apple). Copy the [logo](https://github.com/JanssenProject/jans/raw/main/docs/script-catalog/agama/inboundID/apple/apple.png) to your server at `/opt/jans/jetty/jans-auth/agama/fl/inboundID`, if desired.

## Supply configurations

Create a json fragment using the below as a guide:

```
{
"authzEndpoint": "https://appleid.apple.com/auth/authorize",
"tokenEndpoint": "https://appleid.apple.com/auth/token",
"clientId": "<SERVICE ID>",
"key": "<ONE-LINER CONTENTS OF KEY FILE>",
"keyId": "<KEY ID>",
"teamId": "<TEAM ID>",
"scopes": ["email", "name"],
"custParamsAuthReq": { "response_mode": "form_post" },
"clientCredsInRequestBody": true
}
```

For the `key`, remove the lines regarding begin/end of the private key entirely. Also remove any line breaks: a one-liner is required.

Use the crafted JSON content to parameterize this flow, as in [Set configuration parameters](../README.md#set-configuration-parameters).

Then use the below to [parameterize the main flow](../README.md#parameterize-the-main-flow):

```
"apple": {
"flowQname": "io.jans.inbound.Apple",
"displayName": "Apple",
"mappingClassField": "io.jans.inbound.Mappings.APPLE",
"logoImg": "apple.png"
}
```

## Expected journey

The accompanying images illustrate the steps end-users will go through when using the inbound identity flow taking the Apple route:

*Initial provider selector page*

![provider selector](provider_selector.png)

*Prompt for credentials at Apple website*

![prompt credentials](SIWA_creds.png)

*Prompt for a second factor, e.g. SMS (optional)*

![prompt second factor](SIWA_MFA.png)

*Prompt for browser trust*

![browser trust](SIWA_trust.png)

*Prompt to before returning to original site*

![prompt continue](SIWA_proceed.png)

Finally, the user should land at the target application.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.