Skip to content

Commit

Permalink
docs: update sections on autologin and sessions
Browse files Browse the repository at this point in the history
  • Loading branch information
tronghn committed Oct 3, 2023
1 parent 2e21dae commit 91cd58d
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 12 deletions.
2 changes: 1 addition & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ The following flags are available:

| Flag | Type | Description | Default Value |
|:----------------------------------|:---------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------|
| `auto-login` | boolean | Automatically redirect all HTTP GET requests to login if the user does not have a valid session for all matching upstream paths. | |
| `auto-login` | boolean | Enforce authentication if the user does not have a valid session for all matching upstream paths. Automatically redirects HTTP navigation requests to login, otherwise responds with 401 with the Location header set. | |
| `auto-login-ignore-paths` | strings | Comma separated list of absolute paths to ignore when `auto-login` is enabled. Supports basic wildcard matching with glob-style asterisks. Invalid patterns are ignored. | |
| `bind-address` | string | Listen address for public connections. | `127.0.0.1:3000` |
| `cookie-prefix` | string | Prefix for cookie names. | `io.nais.wonderwall` |
Expand Down
14 changes: 11 additions & 3 deletions docs/sessions.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
# Session Management

Sessions are stored server-side; we only store a session identifier at the end-user's user agent.
When a user authenticates themselves, they receive a session. Sessions are stored server-side; we only store a session identifier at the end-user's user agent.

A session has three states:

- _active_ - the session is valid
- _inactive_ - the session has reached the _inactivity timeout_ and is considered invalid
- _expired_ - the session has reached its _maximum lifetime_ and is considered invalid

Requests with an _invalid_ session are considered _unauthenticated_.

## Session Metadata

Expand All @@ -11,7 +19,7 @@ User agents can access their own session metadata by using [the `/oauth2/session
Every session has a maximum lifetime.
The lifetime is indicated by the `session.ends_at` and `session.ends_in_seconds` fields in the session metadata.

When the session reaches the maximum lifetime, it is considered to be _expired_ or _ended_, after which the user is essentially unauthenticated.
When the session reaches the maximum lifetime, it is considered to be _expired_, after which the user is essentially unauthenticated.
A new session must be acquired by redirecting the user to [the `/oauth2/login` endpoint](endpoints.md#oauth2login) again.

The maximum lifetime can be configured with the `session.max-lifetime` flag.
Expand Down Expand Up @@ -42,7 +50,7 @@ In SSO mode, tokens can not be automatically refreshed. They must be refreshed b
A session can be marked as _inactive_ before it _expires_ (reaches the maximum lifetime).
This happens if the time since the last _refresh_ exceeds the given _inactivity timeout_.

An inactive session _cannot_ be refreshed; a new session must be acquired by redirecting the user to the `/oauth2/login` endpoint.
An _inactive_ session _cannot_ be refreshed; a new session must be acquired by redirecting the user to the `/oauth2/login` endpoint.
This is useful if you want to ensure that an end-user can re-authenticate with the identity provider if they've been gone from an authenticated session for some time.

Inactivity support is enabled with the `session.inactivity` option, which also requires `session.refresh`.
Expand Down
35 changes: 28 additions & 7 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,36 @@ When you must authenticate a user, redirect to the user to [the `/oauth2/login`

#### 1.1. Autologin

The `auto-login` option (disabled by default) will configure Wonderwall to automatically redirect any HTTP `GET` requests to the login endpoint if the user does not have a valid session.
It will automatically set the `redirect` parameter for logins to the URL for the original request so that the user is redirected back to their intended location after login.
The `auto-login` option will configure Wonderwall to enforce authentication for **all** requests, except for the paths that are explicitly [excluded](configuration.md#auto-login-ignore-paths).

You should still check the `Authorization` header for a token and validate the token.
This is especially important as auto-login will **NOT** trigger for HTTP requests that are not `GET` requests, such as `POST` or `PUT`.
If the user is _unauthenticated_ or has an [_inactive_ or _expired_ session](sessions.md), all requests will be short-circuited (i.e. return early and **not** proxied to your application).
The short-circuited response depends on whether the request is a _top-level navigation_ request or not.
A _top-level navigation_ request has the following properties:

To ensure smooth end-user experiences whenever their session expires, your application must thus actively validate and
properly handle such requests. For example, your application might respond with an HTTP 401 to allow frontends to
cache or store payloads before redirecting them back to the login endpoint.
1. Is a `GET` request
2. Has the Fetch metadata headers `Sec-Fetch-Dest=document` and `Sec-Fetch-Mode=navigate`

If the user agent does not support the Fetch metadata headers, we look for an `Accept` header that includes `text/html`.

A _top-level navigation_ request results in a HTTP 302 Found response with the `Location` header pointing to [the `/oauth2/login` endpoint](endpoints.md#oauth2login).
The `redirect` parameter in the login URL is automatically set to the URL for the original request, so that the user is redirected back to their intended location after login.

Other requests are considered non-navigational requests, and they will result in a HTTP 401 Unauthorized response.
The `Location` header is set as before, and a JSON response is included for convenience:

```json
{
"correlation_id": "388d19c6-d439-4ff3-a77f-0ac3421418b2",
"error": "unauthenticated",
"error_description": "request is not authenticated, please log in",
"login_url": "/oauth2/login?redirect=http%3A%2F%2Flocalhost%3A3000%2Fasdf"
}
```

The `redirect` parameter in the login URL is set to the value found in the `Referer` header, so that the user is redirected back to their intended location after login.
If the `Referer` header is empty, the `redirect` parameter is set to the matching ingress path for the original request.

For defence in depth, you should still check the `Authorization` header for a token and validate the token even when using auto-login.

### 2. Logout

Expand Down
2 changes: 1 addition & 1 deletion pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func Initialize() (*Config, error) {
flag.Duration(ShutdownGracefulPeriod, 30*time.Second, "Graceful shutdown period when receiving a shutdown signal after which the server is forcibly exited.")
flag.Duration(ShutdownWaitBeforePeriod, 0*time.Second, "Wait period when receiving a shutdown signal before actually starting a graceful shutdown. Useful for allowing propagation of Endpoint updates in Kubernetes.")

flag.Bool(AutoLogin, false, "Automatically redirect all HTTP GET requests to login if the user does not have a valid session for all matching upstream paths.")
flag.Bool(AutoLogin, false, "Enforce authentication if the user does not have a valid session for all matching upstream paths. Automatically redirects HTTP navigation requests to login, otherwise responds with 401 with the Location header set.")
flag.StringSlice(AutoLoginIgnorePaths, []string{}, "Comma separated list of absolute paths to ignore when 'auto-login' is enabled. Supports basic wildcard matching with glob-style asterisks. Invalid patterns are ignored.")
flag.String(CookiePrefix, "io.nais.wonderwall", "Prefix for cookie names.")
flag.String(EncryptionKey, "", "Base64 encoded 256-bit cookie encryption key; must be identical in instances that share session store.")
Expand Down

0 comments on commit 91cd58d

Please sign in to comment.