> For the complete documentation index, see [llms.txt](https://docs.fortifiedid.se/authn/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.fortifiedid.se/authn/readme.md).

# AuthN

Configuration reference for the AuthN module and its common authenticator settings.

## Introduction

The `AuthN` module deploys authenticators and exposes them through HTTP endpoints. Each authenticator performs a specific type of authentication.

`AuthN` is an HTTP module and supports the [common HTTP module configuration](https://docs.fortifiedid.se/modules/configuration).

Use an [HTTP listener](https://docs.fortifiedid.se/common/server/http-listener) to provide the network endpoint.

## Configuration

{% hint style="info" %}
**Module name:** `AuthN`
{% endhint %}

{% tabs %}
{% tab title="Properties" %}

<table><thead><tr><th>Name</th><th>Description</th><th>Default</th><th data-type="checkbox">Mandatory</th></tr></thead><tbody><tr><td><code>http_context</code></td><td>HTTP context used by the AuthN module and its authenticators.</td><td><code>"/authn"</code></td><td>false</td></tr><tr><td><code>authenticators</code></td><td>List of <a href="#authenticator">authenticators</a> to deploy.</td><td><code>[]</code></td><td>false</td></tr><tr><td><code>cache_control</code></td><td>Cache control policy configuration for static resources. See <a href="#cache-control">cache control</a>.</td><td>See <a href="#cache-control">defaults</a></td><td>false</td></tr><tr><td><code>http_error</code></td><td>Default HTTP <a href="#error-configuration">error configuration</a> passed to authenticators that do not define their own error configuration.</td><td><code>{}</code></td><td>false</td></tr></tbody></table>
{% endtab %}

{% tab title="Example" %}

```json
{
    "name": "AuthN",
    "enabled": true,
    "config": {
        "http_context": "/authn",
        "context_path": "/authn",  
        "webroot_dir": "web/authn",
        "overlay_dir": "/local/custom/authn",
        "authenticators" : [
            {
                "id": "auth01",
                "type": "<auth-type>",
                "config": {
                }
            },
            {
                "id": "auth02",
                "type": "<auth-type>",
                "config": {
                }
            }
        ],
        "http_error": {
            "path_prefix": "web/error",
            "mappings": [
                {
                    "status": "4**",
                    "path": "4xx.html"
                },
                {
                    "status": "*",
                    "path": "error.html"
                }
            ]
        }
    }
}
```

{% endtab %}
{% endtabs %}

### Authenticator

Each object in the `authenticators` list defines one deployable authenticator. Authenticators are deployed independently and support the common HTTP configuration properties.

The order of entries in the list does not affect deployment.

Configuration properties common to all authenticators:

{% tabs %}
{% tab title="Properties" %}

<table data-full-width="true"><thead><tr><th>Name</th><th>Description</th><th>Default</th><th data-type="checkbox">Mandatory</th></tr></thead><tbody><tr><td><code>id</code></td><td>Unique identifier within the current <code>AuthN</code> module.</td><td><code>""</code></td><td>true</td></tr><tr><td><code>type</code></td><td>Registered authenticator type.</td><td><code>""</code></td><td>true</td></tr><tr><td><code>enabled</code></td><td>Controls whether the authenticator is deployed.</td><td><code>true</code></td><td>false</td></tr><tr><td><code>config</code></td><td>Authenticator-specific configuration object.</td><td><code>{}</code></td><td>false</td></tr><tr><td><code>config.context_path</code></td><td>Absolute HTTP path to the authenticator. This path includes the shared <code>http_context</code>. **</td><td><code>""</code></td><td>false</td></tr><tr><td><code>config.base_path</code></td><td>Base path combined with the authenticator <code>id</code> when <code>context_path</code> is omitted.</td><td><code>""</code></td><td>false</td></tr><tr><td><code>config.webroot_dir</code></td><td>Directory from which authenticator resources are served. *</td><td><code>""</code></td><td>false</td></tr><tr><td><code>config.overlay_dir</code></td><td>Directory containing resources that override files in <code>webroot_dir</code>. *</td><td><code>""</code></td><td>false</td></tr><tr><td><code>config.cache_control</code></td><td>Cache-control policies for authenticator resources. See <a href="#cache-control">Cache control</a>.</td><td>See <a href="#cache-control">default policies</a></td><td>false</td></tr><tr><td><code>config.success_location</code></td><td>Redirect target after successful authentication.</td><td><code>""</code></td><td>false</td></tr><tr><td><code>config.failure_location</code></td><td>Redirect target after failed authentication. Supports expression expansion.</td><td><code>""</code></td><td>false</td></tr><tr><td><code>config.cancel_location</code></td><td>Redirect target after cancelled authentication. Supports expression expansion.</td><td><code>""</code></td><td>false</td></tr><tr><td><code>config.expiry</code></td><td>How long the authentication result remains valid, expressed as an ISO-8601 duration.</td><td><code>"PT30M"</code></td><td>false</td></tr><tr><td><code>config.require_chain</code></td><td>Requires the authenticator to run as part of an authentication chain.</td><td><code>true</code></td><td>false</td></tr><tr><td><code>config.exports</code></td><td>Properties copied to the global authenticator state when authentication completes. See <a href="#exports">Exports</a>.</td><td><code>[]</code></td><td>false</td></tr><tr><td><code>config.http_error</code></td><td>Authenticator-specific <a href="#error-configuration">HTTP error configuration</a>.</td><td><code>{}</code></td><td>false</td></tr><tr><td><code>config.logout_location</code></td><td>Redirect target after local logout for authenticators that use the default logout manager.</td><td><code>""</code></td><td>false</td></tr><tr><td><code>config.logout_suffix</code></td><td>Suffix appended to the authenticator route to form the logout route.</td><td><code>"/logout"</code></td><td>false</td></tr><tr><td><code>config.enable_throttling</code></td><td>When enabled, rejects concurrent requests for the same session with HTTP status <code>429</code>.</td><td><code>false</code></td><td>false</td></tr><tr><td><code>config.header_whitelist_default</code></td><td>Replaces the built-in list of request headers exposed to the authenticator.</td><td>See <a href="#request-header-whitelist">defaults</a></td><td>false</td></tr><tr><td><code>config.header_whitelist</code></td><td>Adds request-header names to the effective whitelist. Matching is case-insensitive.</td><td><code>[]</code></td><td>false</td></tr><tr><td><code>config.logout_redir_pattern</code></td><td>Regular expression that defines the allowed <a href="#logout-redirect">logout redirect</a> destinations.</td><td>Local redirects only</td><td>false</td></tr><tr><td><code>config.logout_redir_pattern_prefix</code></td><td>Prefix added to the logout redirect regular expression.</td><td><code>""</code></td><td>false</td></tr><tr><td><code>config.logout_redir_pattern_suffix</code></td><td>Suffix added to the logout redirect regular expression.</td><td><code>""</code></td><td>false</td></tr></tbody></table>
{% endtab %}

{% tab title="Example" %}

```json
{
    "id": "auth01",
    "type": "<auth-type>",
    "config": {
        "base_path": "/test/authn",
        "webroot_dir": "resources/web",
        "overlay_dir": "/opt/local/web",
        "success_location": "/test/app",
        "failure_location": "/test/login_failed.html",
        "logout_redir_pattern": "https://example.org/loggedout.html",
        "http_error": {
            "mappings": [
                {
                    "status": 401,
                    "path": "web/error/custom.html"
                }
            ]
        }
    }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
The `success_location`, `failure_location`, and `cancel_location` redirect targets support authenticator expression expansion.
{% endhint %}

Example:

```json
{
    "failure_location": "/authn/failure.html?trace_id=${session.trace_id}"
}
```

For example, this can pass the current trace ID to a custom error endpoint.

\*) Part of the common HTTP configuration. Additional properties are described in the [HTTP module configuration](https://docs.fortifiedid.se/modules/configuration).

\*\*) For an authenticator, `context_path` is the complete path and includes the module's `http_context`. In general HTTP module configuration, `context_path` is instead relative to `http_context`.

As an alternative, specify `base_path`. The module then combines it with the authenticator `id` to form `context_path`, so you do not need to specify `context_path` directly.

For the authenticator types covered by this documentation, `context_path` takes precedence if both properties are specified.

### Request-header whitelist

Only whitelisted request headers are exposed through the authentication context. `header_whitelist_default` replaces the built-in list, while `header_whitelist` adds names to it.

The built-in whitelist contains:

* `Forwarded`
* `X-Forwarded-For`
* `X-Forwarded-Host`
* `X-Forwarded-Proto`
* `X-SSL-Client-Cert`
* `X-SSL-Client-Chain`
* `X-SSL-Client-Subject`
* `X-SSL-Client-Verify`
* `X-SSL-Protocol`

### Exports

Exports are configurable properties copied to the global authenticator state when authentication completes.

An exported value can be a static value or an expansion expression. The following scopes are available during expansion:

* `session` (the current session)
* `state` (authenticator-local state)

Session properties available during expansion:

| Name       | Description                   | Example               |
| ---------- | ----------------------------- | --------------------- |
| `id`       | Session ID                    | `${session.id}`       |
| `trace_id` | Current trace ID              | `${session.trace_id}` |
| `*`        | Named value stored in session | `${session.name}`     |

{% tabs %}
{% tab title="Properties" %}

<table><thead><tr><th>Name</th><th>Description</th><th>Default</th><th data-type="checkbox">Mandatory</th><th data-type="checkbox">Expanded</th></tr></thead><tbody><tr><td><code>name</code></td><td>Name of the exported property.</td><td></td><td>true</td><td>false</td></tr><tr><td><code>value</code></td><td>Value of the exported property. String values support expression expansion.</td><td></td><td>true</td><td>true</td></tr></tbody></table>
{% endtab %}

{% tab title="Example" %}

```json
{
    "exports": [
        {
            "name": "export01",
            "value": "static export value"
        },
        {
            "name": "export02",
            "value": "${session.trace_id}"
        }
    ]
}
```

{% endtab %}
{% endtabs %}

### Error configuration

AuthN can serve a custom page when an HTTP error occurs. Configure the `http_error` object at module level to provide defaults for all authenticators, or on an individual authenticator to override those defaults. If no error page is configured, AuthN displays a standard page containing the HTTP status code and message.

{% tabs %}
{% tab title="Properties" %}

<table><thead><tr><th>Name</th><th>Description</th><th>Default</th><th data-type="checkbox">Mandatory</th></tr></thead><tbody><tr><td><code>path_prefix</code></td><td>Common path prepended to each <code>mappings.path</code> value.</td><td></td><td>false</td></tr><tr><td><code>mappings</code></td><td>Mappings from HTTP status codes to error-page templates.</td><td></td><td>false</td></tr><tr><td><code>mappings.status</code></td><td>Exact status code or pattern used to select this mapping.</td><td></td><td>true</td></tr><tr><td><code>mappings.path</code></td><td>Path to an error-page template. Use either <code>path</code> or <code>template</code>.</td><td></td><td>false</td></tr><tr><td><code>mappings.template</code></td><td>Inline error-page template. Use either <code>template</code> or <code>path</code>.</td><td></td><td>false</td></tr></tbody></table>
{% endtab %}

{% tab title="Example" %}

```json
{
    "http_error": {
        "path_prefix": "web/error",
        "mappings": [
            {
                "status": 404,
                "template": "<html><head><title>Error {{status.code}}</title></head><body>{{status.code}} {{status.message}} (id: {{trace_id}})</body></html>"
            },
            {
                "status": "4**",
                "path": "4xx.html"
            },
            {
                "status": "*",
                "path": "error.html"
            }
        ]
    }
}
```

{% endtab %}
{% endtabs %}

#### Status code expression

A status expression can be an exact integer code, such as `404`, or a pattern such as `"4**"`. Each asterisk (`*`) in a pattern represents one digit from `0` to `9`. Use `"*"` to match any status code.

#### Error page templating

Error pages are rendered from templates on demand. A template can contain expansion expressions such as `{{trace_id}}` and `{{status.code}}`. The following values are available:

{% tabs %}
{% tab title="Properties" %}

| Name             | Description                         |
| ---------------- | ----------------------------------- |
| `status.code`    | HTTP status code                    |
| `status.message` | HTTP status message (reason phrase) |
| `reason`         | Exception message (if available)    |
| `path`           | Current request path                |
| `session_id`     | Current session ID                  |
| `trace_id`       | Current trace ID                    |
| {% endtab %}     |                                     |

{% tab title="Example" %}

```html
<!-- Simple error template -->
<html>
    <head><title>Error {{status.code}}</title></head>
    <body>
        <div>{{status.code}} {{status.message}}</div>
        <div>({{session_id}} / {{trace_id}})</div>
    </body>
</html>
```

{% endtab %}
{% endtabs %}

Place resources referenced by the template, such as images or style sheets, in a published web root so that the browser can load them.

### Cache control

Use the `cache_control` configuration property to add `Cache-Control` headers to static resources served by the AuthN module or an authenticator. Its `policies` list maps glob patterns to header values. Policies are evaluated in order, and the first matching pattern is applied.

`cache_control` can be set at module level (applies to common resources) and at authenticator level (applies to authenticator-specific resources). Authenticator-level configuration overrides the module-level configuration when set.

{% tabs %}
{% tab title="Properties" %}

<table><thead><tr><th>Name</th><th>Description</th><th>Default</th><th data-type="checkbox">Mandatory</th></tr></thead><tbody><tr><td><code>policies</code></td><td>List of cache control policies. Evaluated in order; first match wins.</td><td></td><td>true</td></tr><tr><td><code>policies.pattern</code></td><td>Glob pattern matched against the request path.</td><td></td><td>true</td></tr><tr><td><code>policies.value</code></td><td><code>Cache-Control</code> header value applied when the pattern matches.</td><td></td><td>true</td></tr><tr><td><code>policies.override</code></td><td>If <code>true</code>, overwrites an existing <code>Cache-Control</code> header. If <code>false</code>, only sets the header when none is present.</td><td><code>true</code></td><td>false</td></tr></tbody></table>
{% endtab %}

{% tab title="Default policies" %}
The following policies are applied by default when `cache_control` is not configured:

```json
{
    "cache_control": {
        "policies": [
            {
                "pattern": "**/assets/**",
                "value": "public, immutable, max-age=86400",
                "override": true
            },
            {
                "pattern": "**.{js,css,json,png,jpg,jpeg,gif,svg,webp,ico,woff,woff2,ttf,eot}",
                "value": "public, immutable, max-age=86400",
                "override": true
            },
            {
                "pattern": "**",
                "value": "no-store, no-transform, max-age=0",
                "override": true
            }
        ]
    }
}
```

{% endtab %}

{% tab title="Example" %}

```json
{
    "cache_control": {
        "policies": [
            {
                "pattern": "**/assets/**",
                "value": "public, immutable, max-age=86400"
            },
            {
                "pattern": "**.{js,css}",
                "value": "public, max-age=3600"
            },
            {
                "pattern": "**",
                "value": "no-store, no-transform, max-age=0"
            }
        ]
    }
}
```

{% endtab %}
{% endtabs %}

### Logout redirect

To prevent malicious redirects after logout, AuthN validates every redirect destination against `logout_redir_pattern`. By default, only local destinations without a scheme, host, or port are allowed.

Use `logout_redir_pattern_prefix` and `logout_redir_pattern_suffix` to extend the default regular expression without replacing it.

The prefix, default pattern, and suffix must form a valid regular expression when combined.

Example:

```json
{
    "logout_redir_pattern_prefix": "https://example\\.org/loggedout|"
}
```

This example allows `https://example.org/loggedout` in addition to the local destinations allowed by the default expression.

If a redirect destination does not match the expression, AuthN rejects it and logs the following error:

```
Invalid redirect location: <location>
```
