mirror of https://github.com/authelia/authelia.git
316 lines
18 KiB
Markdown
316 lines
18 KiB
Markdown
---
|
|
title: "Frequently Asked Questions"
|
|
description: "Frequently Asked Questions regarding integrating the Authelia OpenID Connect 1.0 Provider with an OpenID Connect 1.0 Relying Party"
|
|
summary: "Frequently Asked Questions regarding integrating the Authelia OpenID Connect 1.0 Provider with an OpenID Connect 1.0 Relying Party."
|
|
date: 2022-10-20T15:27:09+11:00
|
|
draft: false
|
|
images: []
|
|
weight: 615
|
|
toc: true
|
|
seo:
|
|
title: "" # custom title (optional)
|
|
description: "" # custom description (recommended)
|
|
canonical: "" # custom canonical URL (optional)
|
|
noindex: false # false (default) or true
|
|
---
|
|
|
|
## Questions
|
|
|
|
The following section lists individual questions.
|
|
|
|
### How do I generate a client identifier or client secret?
|
|
|
|
We strongly recommend the following guidelines for generating a client identifier or client secret:
|
|
|
|
1. Each client should have a unique identifier and secret pair.
|
|
2. Each identifier and secret should be randomly generated.
|
|
3. Each identifier and secret should have a length above 40 characters.
|
|
4. The secret should be stored in the configuration in a supported hash format. *__Note:__ This does not
|
|
mean you configure the relying party / client application with a hashed secret, the hashed secret should just be used
|
|
for the `client_secret` value in the Authelia client configuration and the relying party / client application should
|
|
have the plain text secret.*
|
|
5. Identifiers and Secrets should only have [RFC3986 Unreserved Characters] as some implementations do not appropriately
|
|
encode the identifier or secret when using it to access the token endpoint. See
|
|
[Why does Authelia return an error about the client identifier or client secret being incorrect when they are correct]
|
|
FAQ on this specific issue for more information.
|
|
|
|
[Why does Authelia return an error about the client identifier or client secret being incorrect when they are correct]: #why-does-authelia-return-an-error-about-the-client-identifier-or-client-secret-being-incorrect-when-they-are-correct
|
|
|
|
Authelia provides an easy way to perform such actions.
|
|
|
|
#### Client ID / Identifier
|
|
|
|
Users can easily generate a client id / identifier by following the [Generating a Random Alphanumeric String] guide. For
|
|
example users can perform the below command to generate a client id / identifier with 72 characters
|
|
which is printed. This random command also avoids issues with
|
|
a relying party / client application encoding the characters correctly as it uses the [RFC3986 Unreserved Characters].
|
|
|
|
If a different charset is used if the value would be different when URL encoded then it will also print this value
|
|
separately.
|
|
|
|
{{< envTabs "Generate a Random Client ID" >}}
|
|
{{< envTab "Docker" >}}
|
|
```bash
|
|
docker run --rm authelia/authelia:latest authelia crypto rand --length 72 --charset rfc3986
|
|
```
|
|
{{< /envTab >}}
|
|
{{< envTab "Bare-Metal" >}}
|
|
```bash
|
|
authelia crypto rand --length 72 --charset rfc3986
|
|
```
|
|
{{< /envTab >}}
|
|
{{< /envTabs >}}
|
|
|
|
[Generating a Random Alphanumeric String]: ../../reference/guides/generating-secure-values.md#generating-a-random-alphanumeric-string
|
|
|
|
#### Client Secret
|
|
|
|
Users can easily generate a client secret by following the [Generating a Random Password Hash] guide. For example users
|
|
can perform the below command to both generate a client secret with 72 characters which is printed and is to be used
|
|
with the relying party and hash it using PBKDF2 which can be stored in the Authelia configuration. This random command
|
|
also avoids issues with a relying party / client application encoding the characters correctly as it uses the
|
|
[RFC3986 Unreserved Characters].
|
|
|
|
If a different charset is used if the value would be different when URL encoded then it will also print this value
|
|
separately.
|
|
|
|
{{< envTabs "Generate a Random Client Secret" >}}
|
|
{{< envTab "Docker" >}}
|
|
```bash
|
|
docker run --rm authelia/authelia:latest authelia crypto hash generate pbkdf2 --variant sha512 --random --random.length 72 --random.charset rfc3986
|
|
```
|
|
{{< /envTab >}}
|
|
{{< envTab "Bare-Metal" >}}
|
|
```bash
|
|
authelia crypto hash generate pbkdf2 --variant sha512 --random --random.length 72 --random.charset rfc3986
|
|
```
|
|
{{< /envTab >}}
|
|
{{< /envTabs >}}
|
|
|
|
[Generating a Random Password Hash]: ../../reference/guides/generating-secure-values.md#generating-a-random-password-hash
|
|
|
|
##### Tuning work factors
|
|
|
|
When hashing the client secrets, Authelia performs the hashing operation to authenticate the client when receiving requests.
|
|
This hashing operation takes time by design (the *work* part of the work factor) to hinder an attacker trying to obtain the client secret.
|
|
The amount of time taken depends on your hardware and the work factor.
|
|
|
|
If your client operations time out, you might need to reduce the work factor to a level appropriate for your client and
|
|
your hardware's capabilities.
|
|
|
|
To test the duration of different work factors, you can measure it like this:
|
|
`time authelia crypto hash generate pbkdf2 --variant sha512 --iterations 310000 --password insecure_password`.
|
|
|
|
{{< callout context="note" title="Note" icon="outline/info-circle" >}}
|
|
You should not use your actual passwords for this test, the time taken should be the same for any reasonable password
|
|
length.
|
|
{{< /callout >}}
|
|
|
|
You can read more about password hashing tuning in the
|
|
[Passwords reference guide](../../reference/guides/passwords.md#tuning).
|
|
|
|
##### Plaintext
|
|
|
|
Authelia *technically* supports storing the plaintext secret in the configuration. This will likely be completely
|
|
unavailable in the future as it was a mistake to implement it like this in the first place. While some other OpenID
|
|
Connect 1.0 providers operate in this way, it's more often than not that they operating in this way in error. The
|
|
current *technical support* for this is only to prevent massive upheaval to users and give them time to migrate.
|
|
|
|
As per [RFC6819 Section 5.1.4.1.3](https://datatracker.ietf.org/doc/html/rfc6819#section-5.1.4.1.3) the secret should
|
|
only be stored by the authorization server as hashes / digests unless there is a very specific specification or protocol
|
|
that is implemented by the authorization server which requires access to the secret in the clear to operate properly in
|
|
which case the secret should be encrypted and not be stored in plaintext. The most likely long term outcome is that the
|
|
client configurations will be stored in the database with the secret both salted and peppered.
|
|
|
|
Authelia currently does not implement any of the specifications or protocols which require secrets being accessible in
|
|
the clear such as most notably the `client_secret_jwt` grant, we will however likely soon implement `client_secret_jwt`.
|
|
We are however *__strongly discouraging__* and formally deprecating the use of plaintext client secrets for purposes
|
|
outside those required by specifications. We instead recommended that users remove this from their configuration
|
|
entirely and use the [How Do I Generate a Client Identifier or Client Secret](#how-do-i-generate-a-client-identifier-or-client-secret) FAQ.
|
|
|
|
Plaintext is either denoted by the `$plaintext$` prefix where everything after the prefix is the secret. In addition if
|
|
the secret does not start with the `$` character it's considered as a plaintext secret for the time being but is
|
|
deprecated as is the `$plaintext$` prefix.
|
|
|
|
### Why does Authelia return an error about the client identifier or client secret being incorrect when they are correct?
|
|
|
|
When using `client_secret_basic` several implementations of OAuth 2.0 and OpenID Connect 1.0 do not properly URL encode
|
|
these values as is absolutely required by the specification before encoding the header value. Both the client id and
|
|
client secret must be encoded using the `application/x-www-form-urlencoded` encoding algorithm (i.e. URL encoded) before
|
|
being used as the username and password values for the Basic authorization scheme as detailed in
|
|
[RFC6749 Section 2.3.1](https://datatracker.ietf.org/doc/html/rfc6749#section-2.3.1).
|
|
|
|
Authelia enforces this practice. In situations where the client does not conform to the specification we suggest
|
|
ensuring the client id and client secret only use the unreserved characters or you URL encode these values yourself.
|
|
|
|
For these reasons since v4.38.0 Authelia has included a URL encoded value when generating random strings or password
|
|
hashes if the URL encoded value differs from the non-encoded value.
|
|
|
|
### Why isn't my application able to retrieve the token even though I've consented?
|
|
|
|
The most common cause for this issue is when the affected application can not make requests to the Token [Endpoint].
|
|
This becomes obvious when the log level is set to `debug` or `trace` and a presence of requests to the Authorization
|
|
[Endpoint] without errors (i.e. returns a success) but an absence of requests made to the Token [Endpoint].
|
|
|
|
These requests can be identified by looking at the `path` field in the logs, or by messages prefixed with
|
|
`Authorization Request` indicating a request to the Authorization [Endpoint] and `Access Request` indicating a request
|
|
to the Token [Endpoint]. Therefore if the logs indicate there was an Authorization Request and Access Request this
|
|
specific scenario is not applicable to you.
|
|
|
|
All causes should be clearly logged by the client application, and all errors that do not match this scenario are
|
|
clearly logged by Authelia. It's not possible for us to log requests that never occur however.
|
|
|
|
One potential solution to this is detailed in the [Solution: Configure DNS Appropriately](#configure-dns-appropriately)
|
|
section. This section also details how to identity if you're affected.
|
|
|
|
### Why doesn't the discovery endpoint return the correct issuer and endpoint URL's?
|
|
|
|
The most common cause for this is if the `X-Forwarded-Proto` and `X-Forwarded-Host` / `Host` headers do not match the
|
|
fully qualified URL of the provider. This can be because of requesting from the Authelia port directly i.e. without going
|
|
through your proxy or due to a poorly configured proxy.
|
|
|
|
If you've configured Authelia alongside a proxy and are making a request directly to Authelia you need to perform the
|
|
request via the proxy. If you're avoiding the proxy due to a DNS limitation see
|
|
[Solution: Configure DNS Appropriately](#configure-dns-appropriately) section.
|
|
|
|
### Why doesn't the access control configuration work with OpenID Connect 1.0?
|
|
|
|
The [access control](../../configuration/security/access-control.md) configuration contains several elements which are
|
|
not very compatible with OpenID Connect 1.0. They were designed with per-request authorizations in mind. In particular
|
|
the [resources](../../configuration/security/access-control.md#resources),
|
|
[query](../../configuration/security/access-control.md#query),
|
|
[methods](../../configuration/security/access-control.md#methods), and
|
|
[networks](../../configuration/security/access-control.md#networks) criteria are very specific to each request and to
|
|
some degree so are the [domain](../../configuration/security/access-control.md#domain) and
|
|
[domain regex](../../configuration/security/access-control.md#domain_regex) criteria as the token is issued to the client
|
|
not a specific domain.
|
|
|
|
For these reasons we implemented the
|
|
[authorization policy](../../configuration/identity-providers/openid-connect/clients.md#authorization_policy) as a direct
|
|
option in the client. It's likely in the future that we'll expand this option to encompass the features that work well
|
|
with OpenID Connect 1.0 such as the [subject](../../configuration/security/access-control.md#subject) criteria which
|
|
reasonably be matched to an individual authorization policy. Because the other criteria are mostly geared towards
|
|
per-request authorization these criteria types are fairly unlikely to become part of OpenID Connect 1.0 as there are no
|
|
ways to apply these criteria except during the initial authorization request.
|
|
|
|
See [ADR1](../../reference/architecture-decision-log/1.md) for more information.
|
|
|
|
### Why isn't the Access Token a JSON Web Token?
|
|
|
|
The Access Token and it's format is entirely up to Authorization Servers / OpenID Connect 1.0 Providers. The
|
|
conventional way the Access Token is presented is as an opaque value which has no meaning. There are quite a few reasons
|
|
this is the case, however standards and implementations exist which return the Access Token as a JSON Web Token. This is
|
|
not specifically wrong when they do this, just as the standards allow us to decide the value should be opaque it also
|
|
allows them to decide not to do that.
|
|
|
|
The double-edged sword of a JSON Web Token is it's easy to perform a stateless check to see if a JSON Web Token is
|
|
"valid" but also very hard to revoke it. A Resource Server may just check the JWT claims and signature to see if it
|
|
looks like it *should* still be valid, without performing a stateful check with the Authorization Server frequently
|
|
enough. This is why we *__strongly recommend__* that Access Tokens and ID Tokens have a short lifespan.
|
|
|
|
There also exists standardized mechanisms for Resource Servers and those possessing an opaque Access Token to check the
|
|
validity and metadata associated with them. These mechanisms are the Introspection Request and UserInfo Request.
|
|
|
|
There are some other specific scenarios which would lead to the Access Token being revoked earlier than its original
|
|
lifetime which make this desirable. When you combine these with the fact there are standardized mechanisms to have a
|
|
similar outcome, it's obvious to us this is the sane default.
|
|
|
|
For example during a Refresh Flow to the Token Endpoint the previously issued Access Token and Refresh Token should be
|
|
transparently revoked. This means as soon as a Refresh Flow is performed either by the authorized party or a malicious
|
|
one who's nefariously obtained the Refresh Token, the old Access Token and Refresh Token are effectively useless unless
|
|
the Resource Server is caching these results.
|
|
|
|
In addition as tokens can be manually revoked using the Revocation Endpoint in a scenario where a long lived token was
|
|
revoked due to known compromise; the revocation will take place much faster.
|
|
|
|
Users who still desire or have an application that requires the Access Token is a JWT should configure the
|
|
[access_token_signed_response_alg](../../configuration/identity-providers/openid-connect/clients.md#access_token_signed_response_alg)
|
|
client configuration option.
|
|
|
|
### How should I link user accounts to Authelia OpenID Connect 1.0 responses in the application I'm designing?
|
|
|
|
There are several in-use methodologies for linking user accounts ot OpenID Connect 1.0 Providers. The specification has
|
|
a fairly strong opinion about how this is done for various reasons and the supported method by Authelia is the same as
|
|
what the specification supports.
|
|
|
|
Specifically we support using the combination of the `iss` and `sub` claim as an anchor to local user accounts. This
|
|
combination is a combination that must be unique for any given user identity. Claims such as `email` and
|
|
`preferred_username` have no formal guarantees of stability by the OpenID Connect 1.0 specification.
|
|
|
|
Several in-use applications including ones that Authelia users frequently use utilize claims such as `email` and
|
|
`preferred_username`. However these implementations are in contradiction with the specification. These attributes
|
|
realistically should only be used as hints when a user who has not linked their account tries to login with OpenID
|
|
Connect 1.0 and has not logged in yet. For example an application may prefill the username or email field of a login or
|
|
registration form using these claims.
|
|
|
|
Utilization of these claims could potentially become problematic if we ever implement a feature to change usernames or
|
|
email addresses. Therefore we only guarantee the stability of those specific claims and at such a time as we allow
|
|
changing of usernames or email addresses the link between those values will remain stable, any other claim is to be
|
|
considered fragile.
|
|
|
|
If interested in the specification you can read the
|
|
[Claim Stability and Uniqueness](https://openid.net/specs/openid-connect-core-1_0.html#ClaimStability) section of the
|
|
specification.
|
|
|
|
## Solutions
|
|
|
|
The following section details solutions for multiple of the questions above.
|
|
|
|
### Configure DNS Appropriately
|
|
|
|
In order to make requests to Authelia an application must be able to resolve it. It's important in all instances to
|
|
check if the application with the issue can resolve the correct IP address for Authelia between each step of the
|
|
process, and this check also can be used to clearly identity if this is the most likely underlying cause for an issue
|
|
you're facing.
|
|
|
|
##### Bare-Metal
|
|
|
|
1. If you're running an internal DNS server ensure an A record exists for the FQDN of Authelia with the value being the
|
|
IP of the server responsible for handling requests for Authelia.
|
|
2. If you're not running an internal DNS server then do check the following:
|
|
1. Ensure the external DNS server(s) have the same A record as described above.
|
|
2. Ensure that that your NAT-hairpin is configured correctly.
|
|
3. If all else fails add a hosts file entry to work around this issue.
|
|
|
|
##### Docker
|
|
|
|
1. Ensure both the application with the issue shares a network in common with the proxy container.
|
|
2. Ensure an alias for the FQDN of Authelia is present for the proxy container:
|
|
- If using `docker compose` see the
|
|
[network aliases](https://docs.docker.com/compose/compose-file/compose-file-v3/#aliases) documentation
|
|
reference for more information.
|
|
- If using `docker run` see the `--network-alias` option of the [docker run](https://docs.docker.com/engine/reference/commandline/run/)
|
|
reference for more information.
|
|
|
|
Examples (assuming your Authelia Root URL is `https://{{< sitevar name="subdomain-authelia" nojs="auth" >}}.{{< sitevar name="domain" nojs="example.com" >}}`):
|
|
|
|
```yaml {title="docker-compose.yml"}
|
|
services:
|
|
application:
|
|
## Mandatory that the application is on the same network as the proxy.
|
|
networks:
|
|
proxy: {}
|
|
proxy:
|
|
networks:
|
|
## Mandatory that the proxy is on the same network as the application, and that it has this alias.
|
|
proxy:
|
|
aliases:
|
|
- '{{< sitevar name="subdomain-authelia" nojs="auth" >}}.{{< sitevar name="domain" nojs="example.com" >}}'
|
|
authelia:
|
|
networks:
|
|
proxy: {}
|
|
networks:
|
|
proxy:
|
|
## An external network can be created manually and shared between multiple compose files. This is NOT mandatory.
|
|
external: true
|
|
name: 'proxy-net'
|
|
```
|
|
|
|
```console
|
|
docker run -d --name proxy --network proxy --network-alias {{< sitevar name="subdomain-authelia" nojs="auth" >}}.{{< sitevar name="domain" nojs="example.com" >}} <other proxy arguments>
|
|
docker run -d --name application --network proxy <other application arguments>
|
|
```
|
|
|
|
[Endpoint]: ./introduction.md#discoverable-endpoints
|
|
[RFC3986 Unreserved Characters]: https://datatracker.ietf.org/doc/html/rfc3986#section-2.3
|