Skip to content

Commit

Permalink
feat(session): redirection by cookie domain (#6017)
Browse files Browse the repository at this point in the history
This allows configuring the default redirection URL by session domain. In addition it makes the Authelia URL option in the new session config mandatory at least for the time being.

Signed-off-by: James Elliott <james-d-elliott@users.noreply.github.com>
  • Loading branch information
james-d-elliott committed Sep 28, 2023
1 parent 1a96b5c commit 6a6059d
Show file tree
Hide file tree
Showing 39 changed files with 583 additions and 305 deletions.
27 changes: 16 additions & 11 deletions config.template.yml
Expand Up @@ -27,15 +27,6 @@ theme: 'light'
## set using a secret: https://www.authelia.com/c/secrets
jwt_secret: 'a_very_important_secret'

## Default redirection URL
##
## If user tries to authenticate without any referer, Authelia does not know where to redirect the user to at the end
## of the authentication process. This parameter allows you to specify the default redirection URL Authelia will use
## in such a case.
##
## Note: this parameter is optional. If not provided, user won't be redirected upon successful authentication.
# default_redirection_url: 'https://home.example.com/'

## Set the default 2FA method for new users and for when a user has a preferred method configured that has been
## disabled. This setting must be a method that is enabled.
## Options are totp, webauthn, mobile_push.
Expand Down Expand Up @@ -708,14 +699,28 @@ session:
## Note: the Authelia portal must also be in that domain.
# domain: 'example.com'

## Optional. The fully qualified URI of the portal to redirect users to on proxies that support redirections.
## Required. The fully qualified URI of the portal to redirect users to on proxies that support redirections.
## Rules:
## - MUST use the secure scheme 'https://'
## - The above domain MUST either:
## - The above 'domain' option MUST either:
## - Match the host portion of this URI.
## - Match the suffix of the host portion when prefixed with '.'.
# authelia_url: 'https://auth.example.com'

## Optional. The fully qualified URI used as the redirection location if the portal is accessed directly. Not
## configuring this option disables the automatic redirection behaviour.
##
## Note: this parameter is optional. If not provided, user won't be redirected upon successful authentication
## unless they were redirected to Authelia by the proxy.
##
## Rules:
## - MUST use the secure scheme 'https://'
## - MUST not match the 'authelia_url' option.
## - The above 'domain' option MUST either:
## - Match the host portion of this URI.
## - Match the suffix of the host portion when prefixed with '.'.
# default_redirection_url: 'https://www.example.com'

## Sets the Cookie SameSite value. Possible options are none, lax, or strict.
## Please read https://www.authelia.com/c/session#same_site
# same_site: 'lax'
Expand Down
Expand Up @@ -228,7 +228,8 @@ type, but when it is supported it will include the `query` response mode.

{{< confkey type="string" default="two_factor" required="no" >}}

The authorization policy for this client: either `one_factor` or `two_factor`.
The authorization policy for this client: either `one_factor`, `two_factor`, or one of the ones configured in the
provider [authorization_policies](./provider.md#authorizationpolicies) section.

### lifespan

Expand Down
3 changes: 3 additions & 0 deletions docs/content/en/configuration/miscellaneous/introduction.md
Expand Up @@ -41,6 +41,9 @@ key or the CA public key which signed them (don't add the private key).

{{< confkey type="string" required="no" >}}

*__Important Note:__ You should configure the domain specific redirection URL's in the
[session](../session/introduction.md#defaultredirectionurl) configuration instead of using this option.*

The default redirection URL is the URL where users are redirected when Authelia cannot detect the target URL where the
user was heading.

Expand Down
27 changes: 18 additions & 9 deletions docs/content/en/configuration/session/introduction.md
Expand Up @@ -142,20 +142,29 @@ domains.

#### authelia_url

{{< confkey type="string" required="no" >}}
{{< confkey type="string" required="yes" >}}

This is a required URL which is the root URL of your Authelia installation for this cookie domain which can
be used to generate the appropriate redirection URL when authentication is required. This URL must:

*__Note:__ The AuthRequest implementation does not support redirection control on the authorization server. This means
that the `authelia_url` option is ineffectual for both NGINX and HAProxy, or any other proxy which uses the AuthRequest
implementation.*
1. Be able to read and write cookies for the configured [domain](#domain-1).
2. Use the `https://` scheme.
3. Include the path if relevant (i.e. `https://example.com/authelia` rather than `https://example.com` if you're using
the [server path option](../miscellaneous/server.md#path) of `authelia` and if the Authelia portal is inaccessible from `https://example.com`).

The appropriate query parameter or header for your relevant proxy can override this behaviour.

#### default_redirection_url

{{< confkey type="string" required="no" >}}

This is a completely optional URL which is the root URL of your Authelia installation for this cookie domain which can
be used to generate the appropriate redirection for proxies which support this. This URL must:
This is a completely optional URL which is used as the redirection location when visiting Authelia directly. This option
deprecates the global [default_redirection_url](../miscellaneous/introduction.md#defaultredirectionurl) option. This URL
must:

1. Be able to read and write cookies for the configured [domain](#domain-1).
2. Use the `https://` scheme.
3. Include the path if relevant (i.e. `https://example.com/authelia` rather than `https://example.com` if you're using the
[server path option](../miscellaneous/server.md#path) of `authelia` and if the Authelia portal is inaccessible from
`https://example.com`).
3. Not be the same as the [authelia_url](#autheliaurl)

If this option is absent you must use the appropriate query parameter or header for your relevant proxy.

Expand Down
Expand Up @@ -2,7 +2,7 @@
title: "authelia config template"
description: "Reference for the authelia config template command."
lead: ""
date: 2023-09-20T05:30:57+10:00
date: 2023-09-20T06:21:40+10:00
draft: false
images: []
menu:
Expand Down
13 changes: 7 additions & 6 deletions docs/static/schemas/latest/json-schema/configuration.json
Expand Up @@ -860,6 +860,7 @@
},
"default_redirection_url": {
"type": "string",
"format": "uri",
"title": "The default redirection URL",
"description": "Used to redirect users when they visit the portal directly"
},
Expand Down Expand Up @@ -2578,9 +2579,6 @@
}
]
},
"DisableRememberMe": {
"type": "boolean"
},
"secret": {
"type": "string",
"title": "Secret",
Expand Down Expand Up @@ -2660,9 +2658,6 @@
}
]
},
"DisableRememberMe": {
"type": "boolean"
},
"domain": {
"type": "string",
"format": "hostname",
Expand All @@ -2674,6 +2669,12 @@
"format": "uri",
"title": "Authelia URL",
"description": "The Root Authelia URL to redirect users to for this session cookie"
},
"default_redirection_url": {
"type": "string",
"format": "uri",
"title": "Default Redirection URL",
"description": "The default redirection URL for this cookie domain"
}
},
"additionalProperties": false,
Expand Down
13 changes: 7 additions & 6 deletions docs/static/schemas/v4.38/json-schema/configuration.json
Expand Up @@ -860,6 +860,7 @@
},
"default_redirection_url": {
"type": "string",
"format": "uri",
"title": "The default redirection URL",
"description": "Used to redirect users when they visit the portal directly"
},
Expand Down Expand Up @@ -2578,9 +2579,6 @@
}
]
},
"DisableRememberMe": {
"type": "boolean"
},
"secret": {
"type": "string",
"title": "Secret",
Expand Down Expand Up @@ -2660,9 +2658,6 @@
}
]
},
"DisableRememberMe": {
"type": "boolean"
},
"domain": {
"type": "string",
"format": "hostname",
Expand All @@ -2674,6 +2669,12 @@
"format": "uri",
"title": "Authelia URL",
"description": "The Root Authelia URL to redirect users to for this session cookie"
},
"default_redirection_url": {
"type": "string",
"format": "uri",
"title": "Default Redirection URL",
"description": "The default redirection URL for this cookie domain"
}
},
"additionalProperties": false,
Expand Down
27 changes: 16 additions & 11 deletions internal/configuration/config.template.yml
Expand Up @@ -27,15 +27,6 @@ theme: 'light'
## set using a secret: https://www.authelia.com/c/secrets
jwt_secret: 'a_very_important_secret'

## Default redirection URL
##
## If user tries to authenticate without any referer, Authelia does not know where to redirect the user to at the end
## of the authentication process. This parameter allows you to specify the default redirection URL Authelia will use
## in such a case.
##
## Note: this parameter is optional. If not provided, user won't be redirected upon successful authentication.
# default_redirection_url: 'https://home.example.com/'

## Set the default 2FA method for new users and for when a user has a preferred method configured that has been
## disabled. This setting must be a method that is enabled.
## Options are totp, webauthn, mobile_push.
Expand Down Expand Up @@ -708,14 +699,28 @@ session:
## Note: the Authelia portal must also be in that domain.
# domain: 'example.com'

## Optional. The fully qualified URI of the portal to redirect users to on proxies that support redirections.
## Required. The fully qualified URI of the portal to redirect users to on proxies that support redirections.
## Rules:
## - MUST use the secure scheme 'https://'
## - The above domain MUST either:
## - The above 'domain' option MUST either:
## - Match the host portion of this URI.
## - Match the suffix of the host portion when prefixed with '.'.
# authelia_url: 'https://auth.example.com'

## Optional. The fully qualified URI used as the redirection location if the portal is accessed directly. Not
## configuring this option disables the automatic redirection behaviour.
##
## Note: this parameter is optional. If not provided, user won't be redirected upon successful authentication
## unless they were redirected to Authelia by the proxy.
##
## Rules:
## - MUST use the secure scheme 'https://'
## - MUST not match the 'authelia_url' option.
## - The above 'domain' option MUST either:
## - Match the host portion of this URI.
## - Match the suffix of the host portion when prefixed with '.'.
# default_redirection_url: 'https://www.example.com'

## Sets the Cookie SameSite value. Possible options are none, lax, or strict.
## Please read https://www.authelia.com/c/session#same_site
# same_site: 'lax'
Expand Down
14 changes: 9 additions & 5 deletions internal/configuration/schema/configuration.go
@@ -1,12 +1,16 @@
package schema

import (
"net/url"
)

// Configuration object extracted from YAML configuration file.
type Configuration struct {
Theme string `koanf:"theme" json:"theme" jsonschema:"default=light,enum=auto,enum=light,enum=dark,enum=grey,title=Theme Name" jsonschema_description:"The name of the theme to apply to the web UI"`
CertificatesDirectory string `koanf:"certificates_directory" json:"certificates_directory" jsonschema:"title=Certificates Directory Path" jsonschema_description:"The path to a directory which is used to determine the certificates that are trusted"`
JWTSecret string `koanf:"jwt_secret" json:"jwt_secret" jsonschema:"title=Secret Key for JWT's" jsonschema_description:"Used for signing HS256 JWT's for identity verification"`
DefaultRedirectionURL string `koanf:"default_redirection_url" json:"default_redirection_url" jsonschema:"title=The default redirection URL" jsonschema_description:"Used to redirect users when they visit the portal directly"`
Default2FAMethod string `koanf:"default_2fa_method" json:"default_2fa_method" jsonschema:"enum=totp,enum=webauthn,enum=mobile_push,title=Default 2FA method" jsonschema_description:"When a user logs in for the first time this is the 2FA method configured for them"`
Theme string `koanf:"theme" json:"theme" jsonschema:"default=light,enum=auto,enum=light,enum=dark,enum=grey,title=Theme Name" jsonschema_description:"The name of the theme to apply to the web UI"`
CertificatesDirectory string `koanf:"certificates_directory" json:"certificates_directory" jsonschema:"title=Certificates Directory Path" jsonschema_description:"The path to a directory which is used to determine the certificates that are trusted"`
JWTSecret string `koanf:"jwt_secret" json:"jwt_secret" jsonschema:"title=Secret Key for JWT's" jsonschema_description:"Used for signing HS256 JWT's for identity verification"`
DefaultRedirectionURL *url.URL `koanf:"default_redirection_url" json:"default_redirection_url" jsonschema:"format=uri,title=The default redirection URL" jsonschema_description:"Used to redirect users when they visit the portal directly"`
Default2FAMethod string `koanf:"default_2fa_method" json:"default_2fa_method" jsonschema:"enum=totp,enum=webauthn,enum=mobile_push,title=Default 2FA method" jsonschema_description:"When a user logs in for the first time this is the 2FA method configured for them"`

Log Log `koanf:"log" json:"log" jsonschema:"title=Log" jsonschema_description:"Logging Configuration"`
IdentityProviders IdentityProviders `koanf:"identity_providers" json:"identity_providers" jsonschema:"title=Identity Providers" jsonschema_description:"Identity Providers Configuration"`
Expand Down
2 changes: 2 additions & 0 deletions internal/configuration/schema/keys.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions internal/configuration/schema/session.go
Expand Up @@ -27,15 +27,18 @@ type SessionCookieCommon struct {
Inactivity time.Duration `koanf:"inactivity" json:"inactivity" jsonschema:"default=5 minutes"`
RememberMe time.Duration `koanf:"remember_me" json:"remember_me" jsonschema:"default=30 days"`

DisableRememberMe bool
DisableRememberMe bool `json:"-"`
}

// SessionCookie represents the configuration for a cookie domain.
type SessionCookie struct {
SessionCookieCommon `koanf:",squash"`

Domain string `koanf:"domain" json:"domain" jsonschema:"format=hostname,title=Domain" jsonschema_description:"The domain for this session cookie"`
AutheliaURL *url.URL `koanf:"authelia_url" json:"authelia_url" jsonschema:"format=uri,title=Authelia URL" jsonschema_description:"The Root Authelia URL to redirect users to for this session cookie"`
Domain string `koanf:"domain" json:"domain" jsonschema:"format=hostname,title=Domain" jsonschema_description:"The domain for this session cookie"`
AutheliaURL *url.URL `koanf:"authelia_url" json:"authelia_url" jsonschema:"format=uri,title=Authelia URL" jsonschema_description:"The Root Authelia URL to redirect users to for this session cookie"`
DefaultRedirectionURL *url.URL `koanf:"default_redirection_url" json:"default_redirection_url" jsonschema:"format=uri,title=Default Redirection URL" jsonschema_description:"The default redirection URL for this cookie domain"`

Legacy bool `json:"-"`
}

// SessionRedis represents the configuration related to redis session store.
Expand Down
2 changes: 1 addition & 1 deletion internal/configuration/schema/types.go
Expand Up @@ -19,7 +19,7 @@ import (
"github.com/go-crypt/crypt/algorithm"
"github.com/go-crypt/crypt/algorithm/plaintext"
"github.com/valyala/fasthttp"
yaml "gopkg.in/yaml.v3"
"gopkg.in/yaml.v3"
)

var cdecoder algorithm.DecoderRegister
Expand Down
9 changes: 3 additions & 6 deletions internal/configuration/validator/configuration.go
Expand Up @@ -3,7 +3,6 @@ package validator
import (
"fmt"
"os"
"strings"

"github.com/authelia/authelia/v4/internal/configuration/schema"
"github.com/authelia/authelia/v4/internal/utils"
Expand All @@ -27,10 +26,8 @@ func ValidateConfiguration(config *schema.Configuration, validator *schema.Struc
validator.Push(fmt.Errorf("option 'jwt_secret' is required"))
}

if config.DefaultRedirectionURL != "" {
if err = utils.IsStringAbsURL(config.DefaultRedirectionURL); err != nil {
validator.Push(fmt.Errorf("option 'default_redirection_url' is invalid: %s", strings.ReplaceAll(err.Error(), "like 'http://' or 'https://'", "like 'ldap://' or 'ldaps://'")))
}
if config.DefaultRedirectionURL != nil && !config.DefaultRedirectionURL.IsAbs() {
validator.Push(fmt.Errorf("option 'default_redirection_url' is invalid: the url '%s' is not absolute", config.DefaultRedirectionURL.String()))
}

validateDefault2FAMethod(config, validator)
Expand All @@ -51,7 +48,7 @@ func ValidateConfiguration(config *schema.Configuration, validator *schema.Struc

ValidateRules(config, validator)

ValidateSession(&config.Session, validator)
ValidateSession(config, validator)

ValidateRegulation(config, validator)

Expand Down
8 changes: 5 additions & 3 deletions internal/configuration/validator/configuration_test.go
Expand Up @@ -2,6 +2,7 @@ package validator

import (
"fmt"
"net/url"
"runtime"
"testing"

Expand Down Expand Up @@ -30,7 +31,8 @@ func newDefaultConfig() schema.Configuration {
SessionCookieCommon: schema.SessionCookieCommon{
Name: "authelia_session",
},
Domain: exampleDotCom,
Domain: exampleDotCom,
AutheliaURL: &url.URL{Scheme: "https", Host: "auth." + exampleDotCom},
},
},
}
Expand Down Expand Up @@ -100,13 +102,13 @@ func TestShouldRaiseErrorWithUndefinedJWTSecretKey(t *testing.T) {
func TestShouldRaiseErrorWithBadDefaultRedirectionURL(t *testing.T) {
validator := schema.NewStructValidator()
config := newDefaultConfig()
config.DefaultRedirectionURL = "bad_default_redirection_url"
config.DefaultRedirectionURL = &url.URL{Host: "localhost"}

ValidateConfiguration(&config, validator)
require.Len(t, validator.Errors(), 1)
require.Len(t, validator.Warnings(), 1)

assert.EqualError(t, validator.Errors()[0], "option 'default_redirection_url' is invalid: could not parse 'bad_default_redirection_url' as a URL")
assert.EqualError(t, validator.Errors()[0], "option 'default_redirection_url' is invalid: the url '//localhost' is not absolute")
assert.EqualError(t, validator.Warnings()[0], "access control: no rules have been specified so the 'default_policy' of 'two_factor' is going to be applied to all requests")
}

Expand Down

0 comments on commit 6a6059d

Please sign in to comment.