Skip to content

Commit

Permalink
feat: oauth2 authorization bearer (#6774)
Browse files Browse the repository at this point in the history
This implements user authorization utilizing the OAuth 2.0 bearer scheme (i.e. RFC6750) for both the authorize code grant and client credentials grant. This effectively allows application "passwords" when used with the client credentials grant.

Closes #2023, Closes #188.

Signed-off-by: James Elliott <james-d-elliott@users.noreply.github.com>
  • Loading branch information
james-d-elliott committed Mar 5, 2024
1 parent c70c83f commit fb50f1a
Show file tree
Hide file tree
Showing 61 changed files with 2,526 additions and 528 deletions.
40 changes: 0 additions & 40 deletions config.template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1292,46 +1292,6 @@ notifier:
# 1oAPwIHNaJJwC4z6oG9E_DO_NOT_USE=
# -----END CERTIFICATE-----

## The issuer_private_key is used to sign the JWT forged by OpenID Connect. This is in addition to the
## issuer_private_keys option. Assumed to use the RS256 algorithm, and must not be specified if any of the
## keys in issuer_private_keys also has the algorithm RS256 or are an RSA key without an algorithm.
## Issuer Private Key can also be set using a secret: https://www.authelia.com/c/secrets
# issuer_private_key: |
# -----BEGIN RSA PRIVATE KEY-----
# MIIBPAIBAAJBAK2i7RlJEYo/Xa6mQmv9zmT0XUj3DcEhRJGPVw2qMyadUFxNg/ZF
# p7aTcToHMf00z6T3b7mwdBkCFQOL3Kb7WRcCAwEAAQJBAJdpB0+RQ9ZFwy9Uk38P
# 5zZpUB8cL8ZFeEFluQeVbt0vyNa+cPLvDLouY87onduXtMz5AKIatLaTOjuG2thh
# SKECIQDY6G8gvsYJdXCE9UJ7ukoLrRHxt/frhAtmSY5lVAPuMwIhAMzuDrJo73LH
# ZyEaqIXc5pIiX3Sag43csPDHfuXdtT2NAiEAhyRKGJzDxiDlefFU+sGWYK/z/iYg
# 0Rvz/kbV8UvnJwECIQDAYN6VJ6NZmc27qv33JIejOfdoTEEhZMMKVg1PlxE0ZQIg
# HFpJiFxZES3QvVPr8deBXORPurqD5uU85NKsf61AdRs_DO_NOT_USE=
# -----END RSA PRIVATE KEY-----

## Optional matching certificate chain in PEM DER form that matches the issuer_private_key. All certificates within
## the chain must be valid and current, and from top to bottom each certificate must be signed by the next
## certificate in the chain if provided.
# issuer_certificate_chain: |
# -----BEGIN CERTIFICATE-----
# MIIBWzCCAQWgAwIBAgIQYAKsXhJOXKfyySlmpKicTzANBgkqhkiG9w0BAQsFADAT
# MREwDwYDVQQKEwhBdXRoZWxpYTAeFw0yMzA0MjEwMDA3NDRaFw0yNDA0MjAwMDA3
# NDRaMBMxETAPBgNVBAoTCEF1dGhlbGlhMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJB
# AK2i7RlJEYo/Xa6mQmv9zmT0XUj3DcEhRJGPVw2qMyadUFxNg/ZFp7aTcToHMf00
# z6T3b7mwdBkCFQOL3Kb7WRcCAwEAAaM1MDMwDgYDVR0PAQH/BAQDAgWgMBMGA1Ud
# JQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADQQB8
# Of2iM7fPadmtChCMna8lYWH+lEplj6BxOJlRuGRawxszLwi78bnq0sCR33LU6xMx
# 1oAPwIHNaJJwC4z6oG9E_DO_NOT_USE=
# -----END CERTIFICATE-----
# -----BEGIN CERTIFICATE-----
# MIIBWzCCAQWgAwIBAgIQYAKsXhJOXKfyySlmpKicTzANBgkqhkiG9w0BAQsFADAT
# MREwDwYDVQQKEwhBdXRoZWxpYTAeFw0yMzA0MjEwMDA3NDRaFw0yNDA0MjAwMDA3
# NDRaMBMxETAPBgNVBAoTCEF1dGhlbGlhMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJB
# AK2i7RlJEYo/Xa6mQmv9zmT0XUj3DcEhRJGPVw2qMyadUFxNg/ZFp7aTcToHMf00
# z6T3b7mwdBkCFQOL3Kb7WRcCAwEAAaM1MDMwDgYDVR0PAQH/BAQDAgWgMBMGA1Ud
# JQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADQQB8
# Of2iM7fPadmtChCMna8lYWH+lEplj6BxOJlRuGRawxszLwi78bnq0sCR33LU6xMx
# 1oAPwIHNaJJwC4z6oG9E_DO_NOT_USE=
# -----END CERTIFICATE-----

## Enables additional debug messages.
# enable_client_debug_messages: false

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,17 +211,18 @@ This value does not affect the issued ID Tokens as they are always issued with t

### scopes

{{< confkey type="list(string)" default="openid, groups, profile, email" required="no" >}}
{{< confkey type="list(string)" default="openid,groups,profile,email" required="no" >}}

A list of scopes to allow this client to consume. See
[scope definitions](../../../integration/openid-connect/introduction.md#scope-definitions) for more information. The
documentation for the application you are trying to configure [OpenID Connect 1.0] for will likely have a list of scopes
or claims required which can be matched with the above guide.

The scope values must be one of those documented in the
[scope definitions](../../../integration/openid-connect/introduction.md#scope-definitions) with the exception of when
the configured [grant_types](#grant_types) includes the `client_credentials` grant in which case arbitrary scopes are
also allowed,
The scope values should generally be one of those documented in the
[scope definitions](../../../integration/openid-connect/introduction.md#scope-definitions) with the exception of when a client requires a specific scope we do not define. Users should
expect to see a warning in the logs if they configure a scope not in our definitions with the exception of a client
where the configured [grant_types](#grant_types) includes the `client_credentials` grant in which case arbitrary scopes are
expected,

### grant_types

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,54 @@ with 64 or more characters.

### issuer_private_keys

{{< confkey type="list(object" required="no" >}}
{{< confkey type="list(object)" required="yes" >}}

The list of JWKS instead of or in addition to the [issuer_private_key](#issuer_private_key) and
[issuer_certificate_chain](#issuer_certificate_chain). Can also accept ECDSA Private Key's and Certificates.
The list of issuer JSON Web Keys. At least one of these must be an RSA Private key and be configured with the RS256
algorithm. Can also be used to configure many types of JSON Web Keys for the issuer such as the other RSA based JSON Web
Key formats and ECDSA JSON Web Key formats.

The default key for each algorithm is is decided based on the order of this list. The first key for each algorithm is
The default key for each algorithm is decided based on the order of this list. The first key for each algorithm is
considered the default if a client is not configured to use a specific key id. For example if a client has
[id_token_signed_response_alg](clients.md#id_token_signed_response_alg) `ES256` and [id_token_signed_response_key_id](clients.md#id_token_signed_response_key_id) is
not specified then the first `ES256` key in this list is used.
[id_token_signed_response_alg](clients.md#id_token_signed_response_alg) `ES256` and
[id_token_signed_response_key_id](clients.md#id_token_signed_response_key_id) is not specified then the first `ES256`
key in this list is used.

The following is a contextual example (see below for information regarding each option):

```yaml
identity_providers:
oidc:
issuer_private_keys:
- key_id: 'example'
algorithm: 'RS256'
use: 'sig'
key: |
-----BEGIN RSA PUBLIC KEY-----
MEgCQQDAwV26ZA1lodtOQxNrJ491gWT+VzFum9IeZ+WTmMypYWyW1CzXKwsvTHDz
9ec+jserR3EMQ0Rr24lj13FL1ib5AgMBAAE=
-----END RSA PUBLIC KEY----
certificate_chain: |
-----BEGIN CERTIFICATE-----
MIIBWzCCAQWgAwIBAgIQYAKsXhJOXKfyySlmpKicTzANBgkqhkiG9w0BAQsFADAT
MREwDwYDVQQKEwhBdXRoZWxpYTAeFw0yMzA0MjEwMDA3NDRaFw0yNDA0MjAwMDA3
NDRaMBMxETAPBgNVBAoTCEF1dGhlbGlhMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJB
AK2i7RlJEYo/Xa6mQmv9zmT0XUj3DcEhRJGPVw2qMyadUFxNg/ZFp7aTcToHMf00
z6T3b7mwdBkCFQOL3Kb7WRcCAwEAAaM1MDMwDgYDVR0PAQH/BAQDAgWgMBMGA1Ud
JQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADQQB8
Of2iM7fPadmtChCMna8lYWH+lEplj6BxOJlRuGRawxszLwi78bnq0sCR33LU6xMx
1oAPwIHNaJJwC4z6oG9E_DO_NOT_USE=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIBWzCCAQWgAwIBAgIQYAKsXhJOXKfyySlmpKicTzANBgkqhkiG9w0BAQsFADAT
MREwDwYDVQQKEwhBdXRoZWxpYTAeFw0yMzA0MjEwMDA3NDRaFw0yNDA0MjAwMDA3
NDRaMBMxETAPBgNVBAoTCEF1dGhlbGlhMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJB
AK2i7RlJEYo/Xa6mQmv9zmT0XUj3DcEhRJGPVw2qMyadUFxNg/ZFp7aTcToHMf00
z6T3b7mwdBkCFQOL3Kb7WRcCAwEAAaM1MDMwDgYDVR0PAQH/BAQDAgWgMBMGA1Ud
JQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADQQB8
Of2iM7fPadmtChCMna8lYWH+lEplj6BxOJlRuGRawxszLwi78bnq0sCR33LU6xMx
1oAPwIHNaJJwC4z6oG9E_DO_NOT_USE=
-----END CERTIFICATE-----
```

The following is a contextual example (see below for information regarding each option):

Expand Down Expand Up @@ -248,48 +287,6 @@ The first certificate in the chain must have the public key for the [key](#key),
valid for the current date, and each certificate in the chain should be signed by the certificate immediately following
it if present.

### issuer_private_key

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

The private key used to sign/encrypt the [OpenID Connect 1.0] issued [JWT]'s. The key must be generated by the
administrator and can be done by following the
[Generating an RSA Keypair](../../../reference/guides/generating-secure-values.md#generating-an-rsa-keypair) guide.

This private key is automatically appended to the [issuer_private_keys](#issuer_private_keys) and assumed to be for the
`RS256` algorithm. If provided it is always the first key in this list. As such this key is assumed to be the default
for `RS256` if provided.

The issuer private key *__MUST__*:

* Be a PEM block encoded in the DER base64 format ([RFC4648]).
* Be a RSA private key:
* Encoded in conformance to the [PKCS#8] or [PKCS#1] specifications.
* Have a key size of at least 2048 bits.

[PKCS#8]: https://datatracker.ietf.org/doc/html/rfc5208
[PKCS#1]: https://datatracker.ietf.org/doc/html/rfc8017

If the [issuer_certificate_chain](#issuer_certificate_chain) is provided the private key must include matching public
key data for the first certificate in the chain.

### issuer_certificate_chain

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

The certificate chain/bundle to be used with the [issuer_private_key](#issuer_private_key) DER base64 ([RFC4648])
encoded PEM format used to sign/encrypt the [OpenID Connect 1.0] [JWT]'s. When configured it enables the [x5c] and [x5t]
JSON key's in the JWKs [Discoverable Endpoint](../../../integration/openid-connect/introduction.md#discoverable-endpoints)
as per [RFC7517].

[RFC7517]: https://datatracker.ietf.org/doc/html/rfc7517
[x5c]: https://datatracker.ietf.org/doc/html/rfc7517#section-4.7
[x5t]: https://datatracker.ietf.org/doc/html/rfc7517#section-4.8

The first certificate in the chain must have the public key for the [issuer_private_key](#issuer_private_key), each
certificate in the chain must be valid for the current date, and each certificate in the chain should be signed by the
certificate immediately following it if present.

### enable_client_debug_messages

{{< confkey type="boolean" default="false" required="no" >}}
Expand Down
2 changes: 0 additions & 2 deletions docs/content/en/configuration/methods/secrets.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,6 @@ other configuration using the environment but instead of loading a file the valu
[authentication_backend.ldap.password]: ../first-factor/ldap.md#password
[authentication_backend.ldap.tls.certificate_chain]: ../first-factor/ldap.md#tls
[authentication_backend.ldap.tls.private_key]: ../first-factor/ldap.md#tls
[identity_providers.oidc.issuer_certificate_chain]: ../identity-providers/openid-connect/provider.md#issuer_certificate_chain
[identity_providers.oidc.issuer_private_key]: ../identity-providers/openid-connect/provider.md#issuer_private_key
[identity_providers.oidc.hmac_secret]: ../identity-providers/openid-connect/provider.md#hmac_secret
[identity_validation.reset_password.jwt_secret]: ../identity-validation/reset-password.md#jwt_secret

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "Server Authz Endpoints"
description: "Configuring the Server Authz Endpoint Settings."
lead: "Authelia supports several authorization endpoints on the internal webserver. This section describes how to configure and tune them."
lead: "Authelia supports several authorization endpoints on the internal web server. This section describes how to configure and tune them."
date: 2023-01-25T20:36:40+11:00
draft: false
images: []
Expand All @@ -26,16 +26,22 @@ server:
implementation: 'ForwardAuth'
authn_strategies:
- name: 'HeaderProxyAuthorization'
schemes:
- 'Basic'
- name: 'CookieSession'
ext-authz:
implementation: 'ExtAuthz'
authn_strategies:
- name: 'HeaderProxyAuthorization'
schemes:
- 'Basic'
- name: 'CookieSession'
auth-request:
implementation: 'AuthRequest'
authn_strategies:
- name: 'HeaderAuthRequestProxyAuthorization'
schemes:
- 'Basic'
- name: 'CookieSession'
legacy:
implementation: 'Legacy'
Expand Down Expand Up @@ -80,3 +86,11 @@ immediately short-circuit the authentication, otherwise the next strategy in the
The name of the strategy. Valid case-sensitive values are `CookieSession`, `HeaderAuthorization`,
`HeaderProxyAuthorization`, `HeaderAuthRequestProxyAuthorization`, and `HeaderLegacy`. Read more about the strategies in
the [reference guide](../../reference/guides/proxy-authorization.md#authn-strategies).

#### schemes

{{< confkey type="list(string)" default="Basic" required="no" >}}

The list of schemes allowed on this endpoint. Options are `Basic`, and `Bearer`. This option is only applicable to the
`HeaderAuthorization`, `HeaderProxyAuthorization`, and `HeaderAuthRequestProxyAuthorization` strategies and unavailable
with the `legacy` endpoint which only uses `Basic`.
30 changes: 9 additions & 21 deletions docs/content/en/configuration/miscellaneous/server.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "Server"
description: "Configuring the Server Settings."
lead: "Authelia runs an internal webserver. This section describes how to configure and tune this."
lead: "Authelia runs an internal web server. This section describes how to configure and tune this."
date: 2022-06-15T17:51:47+10:00
draft: false
images: []
Expand Down Expand Up @@ -39,19 +39,7 @@ server:
endpoints:
enable_pprof: false
enable_expvars: false
authz:
forward-auth:
implementation: 'ForwardAuth'
authn_strategies: []
ext-authz:
implementation: 'ExtAuthz'
authn_strategies: []
auth-request:
implementation: 'AuthRequest'
authn_strategies: []
legacy:
implementation: 'Legacy'
authn_strategies: []
authz: {} ## See the dedicated "Server Authz Endpoints" configuration guide.
```

## Options
Expand Down Expand Up @@ -83,9 +71,9 @@ server:

### asset_path

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

Authelia by default serves all static assets from an embedded filesystem in the Go binary.
Authelia by default serves all static assets from an embedded file system in the Go binary.

Modifying this setting will allow you to override and serve specific assets for Authelia from a specified path. All
assets that can be overridden must be placed in the `asset_path`. The structure of this directory and the assets which
Expand All @@ -98,7 +86,7 @@ can be overridden is documented in the

On startup Authelia checks for the existence of /app/healthcheck.sh and /app/.healthcheck.env and if both of these exist
it writes the configuration vars for the healthcheck to the /app/.healthcheck.env file. In instances where this is not
desirable it's possible to disable these interactions entirely.
desirable, it's possible to disable these interactions entirely.

An example situation where this is the case is in Kubernetes when set security policies that prevent writing to the
ephemeral storage of a container or just don't want to enable the internal health check.
Expand Down Expand Up @@ -147,8 +135,8 @@ or intermediate certificates. If no item is provided mutual TLS is disabled.
{{< confkey type="string" required="no" >}}

This customizes the value of the Content-Security-Policy header. It will replace all instances of the below placeholder
with the nonce value of the Authelia react bundle. This is an advanced option to customize and you should do sufficient
research about how browsers utilize and understand this header before attempting to customize it.
with the nonce value of the Authelia react bundle. This is an advanced option to customize, and you should do
sufficient research about how browsers utilize and understand this header before attempting to customize it.

{{< csp >}}

Expand Down Expand Up @@ -195,10 +183,10 @@ Generally this does not need to be configured for most use cases. See the
### Buffer Sizes

The read and write buffer sizes generally should be the same. This is because when Authelia verifies
if the user is authorized to visit a URL, it also sends back nearly the same size response as the request. However
if the user is authorized to visit a URL, it also sends back nearly the same size response as the request. However,
you're able to tune these individually depending on your needs.

### Asset Overrides

If replacing the Logo for your Authelia portal it is recommended to upload a transparent PNG of your desired logo.
If replacing the Logo for your Authelia portal, it is recommended to upload a transparent PNG of your desired logo.
Authelia will automatically resize the logo to an appropriate size to present in the frontend.
10 changes: 8 additions & 2 deletions docs/content/en/configuration/security/access-control.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,14 @@ identify the subject is [one_factor]. See [Rule Matching Concept 2] for more inf

This criteria matches identifying characteristics about the subject. Currently this is either user or groups the user
belongs to. This allows you to effectively control exactly what each user is authorized to access or to specifically
require two-factor authentication to specific users. Subjects are prefixed with either `user:` or `group:` to identify
which part of the identity to check.
require two-factor authentication to specific users. Subjects must be prefixed with the following prefixes to
specifically match a specific part of a subject.

| Subject Type | Prefix | Description |
|:----------------:|:----------------:|:----------------------------------------------------------------------------------------------------------------------------------------------:|
| User | `user:` | Matches the username of a user. |
| Group | `group:` | Matches if the user has a group with this name. |
| OAuth 2.0 Client | `oauth2:client:` | Matches if the request has been authorized via a token issued by a client with the specified id utilizing the `client_credentials` grant type. |

The format of this rule is unique in as much as it is a list of lists. The logic behind this format is to allow for both
`OR` and `AND` logic. The first level of the list defines the `OR` logic, and the second level defines the `AND` logic.
Expand Down
2 changes: 1 addition & 1 deletion docs/content/en/contributing/development/build-and-test.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ aliases:
- /docs/contributing/build-and-dev.html
---

__Authelia__ is built a [React] frontend user portal bundled in a [Go] application which acts as a basic webserver for
__Authelia__ is built a [React] frontend user portal bundled in a [Go] application which acts as a basic web server for
the [React] assets and a dedicated API.

The GitHub repository comes with a CLI dedicated to developers called
Expand Down
13 changes: 13 additions & 0 deletions docs/content/en/integration/openid-connect/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,19 @@ This scope includes the profile information the authentication backend reports a
| preferred_username | string | username | The username the user used to login with |
| name | string | display_name | The users display name |

### Special Scopes

The following scopes represent special permissions granted to a specific token.

#### authelia.bearer.authz

This scope allows the granted access token to be utilized with the bearer authorization scheme on endpoints protected
via Authelia.

The specifics about this scope are discussed in the
[OAuth 2.0 Bearer Token Usage for Authorization Endpoints](oauth-2.0-bearer-token-usage.md#authorization-endpoints)
guide.

## Signing and Encryption Algorithms

[OpenID Connect 1.0] and OAuth 2.0 support a wide variety of signature and encryption algorithms. Authelia supports
Expand Down

0 comments on commit fb50f1a

Please sign in to comment.