13 KiB
title | description | summary | date | draft | images | weight | toc | seo | ||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
OAuth 2.0 Bearer Token Usage | An introduction into utilizing the Authelia OAuth 2.0 Provider as an authorization method | An introduction into utilizing the Authelia OAuth 2.0 Provider as an authorization method. | 2024-03-05T19:11:16+10:00 | false | 611 | true |
|
Access Tokens can be granted which can be leveraged as bearer tokens for the purpose of authorization in place of the Session Cookie Forwarded Authorization Flow. This is performed leveraging the RFC6750: OAuth 2.0 Bearer Token Usage specification.
Authorization Endpoints
A registered OAuth 2.0 client which is
permitted to request the authelia.bearer.authz
scope can request users grant access to a token which can be used
for the forwarded authentication flow integrated into a proxy (i.e. access_control
rules) in place of the standard
session cookie-based authorization flow (which redirects unauthorized users) by utilizing
RFC6750: OAuth 2.0 Bearer Token Usage authorization scheme norms (i.e. using the bearer scheme).
{{< callout context="note" title="Note" icon="outline/info-circle" >}} These tokens are not intended for usage with the Authelia API, a separate exclusive scope (or scopes) and specific audiences will likely be implemented at a later date for this. {{< /callout >}}
General Protections
The following protections have been considered:
- There are several safeguards to ensure this Authorization Flow cannot operate accidentally. It must be explicitly
configured:
- The authorization endpoint must be explicitly configured to allow the
bearer
scheme. See Authorization Endpoint Configuration. - Must be utilizing the new session configuration. See Session Configuration.
- The OpenID Connect 1.0 Provider must be configured.
- One or more OpenID Connect 1.0 Clients must be
registered with the
authelia.bearer.authz
scope and relevant required parameters. - Additional policy requirements are enforced for the client registrations to ensure as much reasonable protection as possible.
- The authorization endpoint must be explicitly configured to allow the
- The token must:
- Be granted the
authelia.bearer.authz
scope. - Be presented via the
bearer
scheme in the header matching your server Authorization Endpoints configuration. See Authorization Endpoint Configuration. - Not be expired, revoked, or otherwise invalid.
- Actually be an Access Token (tokens with the prefix
authelia_at_
, not tokens with the prefixesauthelia_rt_
orauthelia_ac_
).
- Be granted the
- Authorizations using this method have special specific processing rules when considering the access control rules:
- If the token was granted via the
authorization_code
grant then the user who granted the consent for the requested scope and audience and their effective authentication level (1FA or 2FA) will be used to match the configured access control rules. - If the token was granted via the
client_credentials
grant then the token will always be considered as having an authentication level of 1FA and when it comes to matching a subject rule a special subject typeoauth2:client:<id>
will match the token instead of a user or groups (where<id>
is the registered client id). See Access Control Configuration. - The audience of the token is also considered and if the token does not have an audience which is an exact match or the prefix of the URL being requested, the authorization will automatically be denied.
- If the token was granted via the
- At this time, each request using this scheme will cause a lookup to be performed on the authentication backend.
- Specific changes to the client registration will result in the authorization being denied, such as:
- The client is no longer registered.
- The
authelia.bearer.authz
scope is removed from the registration. - The audience which matches the request is removed from the registration.
- The audience of the token must explicitly be requested. Omission of the
audience
parameter may be denied and will not grant any audience (thus making it useless) even if the client has been whitelisted for the particular audience.
For example, if john
consents to grant the token, and it includes the audience https://app1.{{< sitevar name="domain" nojs="example.com" >}}
, but the
user john
is not normally authorized to visit https://app1.{{< sitevar name="domain" nojs="example.com" >}}
the token will not grant access to this resource.
In addition, if john
has his access updated via the access control rules, their groups, etc., then this access is
automatically applied to these tokens.
These rules effectively give both administrators and end-users fine-grained control over which endpoints can utilize this authorization scheme as administrators will be required to allow each individual URL prefix which can be requested and end users will be able to request individual audiences from the allowed list (effectively narrowing the audience of the token).
The following recommendations should be considered by users who use this authorization method:
- Using the JWT Profile for Access Tokens effectively makes the introspection stateless and is discouraged for this purpose unless you have specific performance issues. We would rather find the cause of the performance issues and improve them in an instance where they are noticed.
Audience Request
While not explicitly part of the specifications, the audience
parameter can be used during the Authorization Request
phase of the Authorization Code Grant Flow or the Access Token Request phase of the Client Credentials Grant Flow. The
specification leaves it up to Authorization Server policy specifically how audiences are granted, and this seems like a
common practice.
Authorization Endpoint Configuration
This authorization scheme is not available by default and must be explicitly enabled. The following examples demonstrate how to enable this scheme (along with the basic scheme). See the Server Authz Endpoints configuration guide for more information.
server:
endpoints:
authz:
forward-auth:
implementation: 'ForwardAuth'
authn_strategies:
- name: 'HeaderAuthorization'
schemes:
- 'Basic'
- 'Bearer'
- name: 'CookieSession'
ext-authz:
implementation: 'ExtAuthz'
authn_strategies:
- name: 'HeaderAuthorization'
schemes:
- 'Basic'
- 'Bearer'
- name: 'CookieSession'
auth-request:
implementation: 'AuthRequest'
authn_strategies:
- name: 'HeaderAuthRequestProxyAuthorization'
schemes:
- 'Basic'
- 'Bearer'
- name: 'CookieSession'
legacy:
implementation: 'Legacy'
authn_strategies:
- name: 'HeaderLegacy'
- name: 'CookieSession'
Session Configuration
This feature is only intended to be supported while using the new session configuration syntax. See the example below.
session:
secret: 'insecure_session_secret'
cookies:
- domain: '{{< sitevar name="domain" nojs="example.com" >}}'
authelia_url: 'https://{{< sitevar name="subdomain-authelia" nojs="auth" >}}.{{< sitevar name="domain" nojs="example.com" >}}'
default_redirection_url: 'https://www.{{< sitevar name="domain" nojs="example.com" >}}'
Access Control Configuration
In addition to the restriction of the token audience having to match the target location you must also grant access
in the Access Control section of the configuration either to the user or in the instance of the client_credentials
grant the client itself.
It is important to note that the client_credentials
grant is always treated as 1FA, thus only the one_factor
policy is useful for this grant type.
access_control:
rules:
## The 'app1.{{< sitevar name="domain" nojs="example.com" >}}' domain for the user 'john' regardless if they're using OAuth 2.0 or session based flows.
- domain: 'app1.{{< sitevar name="domain" nojs="example.com" >}}'
policy: 'one_factor'
subject: 'user:john'
## The 'app2.{{< sitevar name="domain" nojs="example.com" >}}' domain for the 'example-three' client when using the 'client_credentials' grant.
- domain: 'app2.{{< sitevar name="domain" nojs="example.com" >}}'
policy: 'one_factor'
subject: 'oauth2:client:example-three'
Client Restrictions
In addition to the above protections, this scope MUST only be configured on clients with strict security rules which must be explicitly set:
- Are not configured with any additional scope with the following exceptions:
- The
offline_access
scope.
- The
- Have both PAR and PKCE with the
S256
challenge enforced. - Have a list of audiences which represent the resources permitted to be allowed by generated tokens.
- Have the
explicit
consent mode. - Only allows the
client_credentials
, or theauthorization_code
andrefresh_token
grant types. - Only allows the
code
response type.- This is not relevant for the
client_credentials
grant type.
- This is not relevant for the
- Only allows the
form_post
orform_post.jwt
response modes.- This is not relevant for the
client_credentials
grant type.
- This is not relevant for the
- Must either:
- Be a public client with the Token Endpoint authentication method
none
. See configuration optiontoken_endpoint_auth_method
. - Be a confidential client with the Token Endpoint authentication method
client_secret_basic
,client_secret_jwt
, orprivate_key_jwt
configured. See configuration optiontoken_endpoint_auth_method
.
Examples
The following examples illustrate how the Client Restrictions should be applied to a client.
Public Client Example
identity_providers:
oidc:
clients:
- client_id: 'example-one'
public: true
require_pkce: true
pkce_challenge_method: 'S256'
redirect_uris:
- 'http://localhost/callback'
scopes:
- 'offline_access'
- 'authelia.bearer.authz'
audience:
- 'https://app1.{{< sitevar name="domain" nojs="example.com" >}}'
- 'https://app2.{{< sitevar name="domain" nojs="example.com" >}}'
grant_types:
- 'authorization_code'
- 'refresh_token'
response_types:
- 'code'
response_modes:
- 'form_post'
consent_mode: 'explicit'
require_pushed_authorization_requests: true
token_endpoint_auth_method: 'none'
Confidential Client Example: Authorization Code Flow
This is likely the most common configuration for most users.
identity_providers:
oidc:
clients:
- client_id: 'example-two'
client_secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng' # The digest of 'insecure_secret'.
public: false
require_pkce: true
pkce_challenge_method: 'S256'
redirect_uris:
- 'http://localhost/callback'
scopes:
- 'offline_access'
- 'authelia.bearer.authz'
audience:
- 'https://app1.{{< sitevar name="domain" nojs="example.com" >}}'
- 'https://app2.{{< sitevar name="domain" nojs="example.com" >}}'
grant_types:
- 'authorization_code'
- 'refresh_token'
response_types:
- 'code'
response_modes:
- 'form_post'
consent_mode: 'explicit'
require_pushed_authorization_requests: true
token_endpoint_auth_method: 'client_secret_basic'
Confidential Client Example: Client Credentials Flow
This example illustrates a method to configure a Client Credential flow for this purpose. This flow is useful for
automations. It's important to note that for access control evaluation purposes this token will match a subject of
oauth2:client:example-three
i.e. the oauth2:client:
prefix followed by the client id.
identity_providers:
oidc:
clients:
- client_id: 'example-three'
client_secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng' # The digest of 'insecure_secret'.
public: false
scopes:
- 'authelia.bearer.authz'
audience:
- 'https://app1.{{< sitevar name="domain" nojs="example.com" >}}'
- 'https://app2.{{< sitevar name="domain" nojs="example.com" >}}'
grant_types:
- 'client_credentials'
token_endpoint_auth_method: 'client_secret_basic'