Skip to content

Commit

Permalink
chore: rework sample-cred-plugin (#7339)
Browse files Browse the repository at this point in the history
* docs: update TOC #7289

Signed-off-by: jgomer2001 <bonustrack310@gmail.com>

* chore: remove previous sample cred plugin #7289

Signed-off-by: jgomer2001 <bonustrack310@gmail.com>

* chore: rewrite sample cred plugin and add docs #7289

Signed-off-by: jgomer2001 <bonustrack310@gmail.com>

---------

Signed-off-by: jgomer2001 <bonustrack310@gmail.com>
  • Loading branch information
jgomer2001 committed Jan 11, 2024
1 parent 1c793fc commit 0152c24
Show file tree
Hide file tree
Showing 30 changed files with 575 additions and 751 deletions.
1 change: 0 additions & 1 deletion docs/casa/administration/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ First, the custom authentication scripts corresponding to the authentication met

Scripts can be more easily looked up by display name. The below table shows the display names of the scripts previously listed:

|-|-|
|Script|Display name|
|-|-|
|OTP (SMS)|twilio_sms|
Expand Down
103 changes: 103 additions & 0 deletions docs/casa/developer/add-authn-methods.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Onboarding custom authentication methods

Out-of-the-box Casa supports some useful authentication methods for a secure, pleasant authentication experience. Adding more authentication mechanisms is possible and requires certain development effort. In this guide we summarize the steps required to do so and give you some useful pointers to start your coding journey.

Supporting a new authentication mechanisms consists of two tasks: coding a custom interception script and creating a plugin that contributes an authentication method. The former has to do with the authentication flow the user experiences (to access Casa or other apps), and the latter with the credential enrollment process.

## Interception script

!!! Note
Acquaintance with [person authentication](../../admin/developer/scripts/person-authentication.md) scripts is required

### About Casa authentication flow

Casa's authentication is backed by a main custom script that determines which authentication methods are currently supported, dynamically imports relevant custom scripts, and orchestrates the general flow while delegating specific implementation details to some of those scripts.

The main script supports backtracking: if a user is asked to present a specific credential and that credential isn't currently available, he can choose an alternative credential by visiting a different page corresponding to the alternative authentication method. Users can backtrack any number of times.

### Script requisites

To code the script corresponding to the authentication method to add, use the `.py` script found [here](https://github.com/JanssenProject/jans/tree/main/jans-casa/plugins/samples/sample-cred) as a canvas. Ensure the following conditions are met so that it properly integrates in the main Casa flow:

- For step 1, `prepareForStep` must only return `True`
- For step 1, `getExtraParametersForStep` must only return `None`
- For step 1, the `authenticate` routine must check if there is already an authenticated user, and if so bypass validating the username and password. This is because a user may have previously attempted authentication with a different method
- `hasEnrollments` routine has a signature like:
`def hasEnrollments(self, configurationAttributes, user):`
where the `configurationAttributes` parameter is a `java.util.Map<String, io.jans.model.SimpleCustomProperty>` and `user` is an instance belonging to `io.jans.as.common.model.common.User`
- `hasEnrollments` must return `True` or `False`, describing whether `user` has one or more credentials enrolled for the type you are interested in
- Keep in mind that `getPageForStep` won't be called when `step=1` in your script. Casa takes charge of this specific step/method combination
- Finally, ensure that custom pages returned by `getPageForStep` for step 2 (or higher) contain the fragment:

```
<ui:include src="/casa/casa.xhtml" />
```

This will display a set of links for the user to navigate to alternate 2FA pages. The list will be shown when clicking on a link which should be provided this way:

```
<a href="javascript:showAlternative('ELEMENT_ID')" id="alter_link" class="green hover-green f7-cust">#{msgs['casa.alternative']}</a>
```

Here `ELEMENT_ID` is the identifier for the HTML node that wraps all visual elements of your page (excluding `casa.xhtml`). It is required to preserve `alter_link` as `id` for the `a` tag.

Adding the script to the server can be done via [TUI](../../admin/config-guide/config-tools/jans-tui/README.md) for instance. Ensure the display name assigned to the script is short and meaningful. Check [here](../administration/quick-start.md#enable-scripts) for examples. This value will be used as "ACR" in the plugin that will have to be developed for the credential enrollment process.

### Key questions

As you code the script, you will come up with some design decisions, for instance:

- How to model and store credentials associated to the authentication method?
- What kind of parameters are relevant for the authentication method?
- What's the algorithm for authenticating users once they have supplied a valid username/password combination?

Depending on the answers, you may like to start instead with plugin development first. This is not always the case though, however, getting your hands on the plugin might help unclutter the path.

## Enrollment plugin

Coding a Casa plugin is mainly a Java development task. You can use the "Sample credential" [plugin](https://github.com/JanssenProject/jans/tree/main/jans-casa/plugins/samples/sample-cred) as a template to start the work. Ensure you have a development environment with:

- Java 11 or higher
- Maven 3.8
- A SSH client tool
- Access to a Jans Server installation that includes Jans Casa. Prefer a VM installation over the CN edition for development purposes

### Plugin deployment

Start with deploying the plugin to get acquainted with the process:

1. Download the `sample-cred` project folder to the local development machine and `cd` to it. You can download the jans repository [here](https://github.com/JanssenProject/jans/archive/refs/heads/main.zip)
1. Run `mvn -o -Dmaven.test.skip package`
1. This will generate a `target` folder with a couple of jar files in it

Access Casa admin console and in the plugins page, upload the file suffixed with `jar-with-dependencies.jar`. After one minute approximately, in a browser hit `https://<hostname>/jans-casa/pl/sample-cred-plugin/user/cred_details.zul`. You will get access to a dummy page.

You can remove the plugin and add it as many times as you like - no restarts are needed. You can do so either via the admin console or by dropping/removing the file directly in the filesystem (the path is `/opt/jans/jetty/jans-casa/plugins`)

### Study the sample project

Now it's time for you to go through the project folder checking one file at a time. Most of files contain comments that explain the purpose of things.

Once you are done, analyze the file `./src/main/resources/assets/user/cred_details.zul`. It contains the markup of the page you visited earlier.

### Enable the authentication method

Once the [interception script](#interception-script) is added to the server (a draft is OK), visit the admin console and enable the [authentication method](../administration/quick-start.md#enable-methods-in-casa) by assigning the plugin just loaded. From here onwards, the left-hand side menu of Casa will have a new item under the "2FA credentials" heading. Additionally a new panel in the user's dashboard will appear and show some detail about the authentication method.

### Additional tweaks

If you alter the `.zul` file and then package and redeploy the plugin, you will most probably not see any change taking effect in the UI page. This is because the ZK framework caches the `.zul` pages by default for a very long period. To change this behavior do the following:

1. Connect to your VM and `cd` to `/opt/gluu/jetty/jans-casa/webapps`
1. Extract ZK descriptor:
```
# jar -xf jans-casa.war WEB-INF/zk.xml
```
1. Locate XML tag `file-check-period` and remove it including its surrounding parent `desktop-config`
1. Save the file and patch the application war:
```
# jar -uf jans-casa.war WEB-INF/zk.xml
```
1. Restart casa (e.g. `systemctl casa restart`)

From now on, any template change will take effect after 5 seconds.
2 changes: 2 additions & 0 deletions docs/casa/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ Casa is a plugin-oriented, Java web application. Existing functionality can be e
- [Custom branding](./plugins/custom-branding.md)
- [2FA settings](./plugins/2fa-settings.md)

If you are interested in onboarding additional authentication methods to Casa, read this [guide](./developer/add-authn-methods.md).

## Janssen Server integration

Janssen Server relies on "interception scripts" to implement user authentication. Casa itself has an interception script which defines authentication logic and routes authentications to specific 2FA mechanisms which also have their own scripts.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,26 @@
import org.pf4j.Extension;

/**
* An extension class implementing the {@link NavigationMenu} extension point.
* Represents a menu item to be added to Casa navigation menu
* @author jgomer
*/
@Extension
public class HelloWorldMenu implements NavigationMenu {

public String getContentsUrl() {
//Location of the template that holds the markup of the menu item to be added.
//See the resource/assets directory
return "menu.zul";
}

public MenuType menuType() {
//Whether this menu item is to be added to the general user menu or the admin-only menu
return MenuType.USER;
}

public float getPriority() {
//A numeric value employed to sort the menu items. Items with higher priority appear
//first in the menu
return 0.5f;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
<z:zk xmlns:z="http://www.zkoss.org/2005/zul" xmlns="native">

<li>
<!-- A link pointing to index.zul file relative to this plugin's URL -->
<a class="db pv3 pl1 ${css.menuItem}" href="${zkService.contextPath}${base}/index.zul">

<!-- some font-awesome icons adorne the menu item-->
<i class="mh2 fas fa-globe" />

<!--
Text of the menu item. The ${labels...} expression refers to a message found in this
plugin's resource bundle. See https://docs.jans.io/head/casa/administration/localization/
-->
<span class="collapsible-menu-item di">${labels.hello.title}</span>

</a>
</li>

Expand Down
8 changes: 0 additions & 8 deletions jans-casa/plugins/samples/sample-cred-plugin/README.md

This file was deleted.

72 changes: 0 additions & 72 deletions jans-casa/plugins/samples/sample-cred-plugin/pom.xml

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Loading

0 comments on commit 0152c24

Please sign in to comment.