Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion authentik/providers/oauth2/views/token.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,19 +393,22 @@ def __post_init_client_credentials_jwt(self, request: HttpRequest):
LOGGER.warning("failed to parse JWT for kid lookup", exc=exc)
raise TokenError("invalid_grant") from None
expected_kid = decode_unvalidated["header"]["kid"]
fallback_alg = decode_unvalidated["header"]["alg"]
for source in self.provider.jwks_sources.filter(
oidc_jwks__keys__contains=[{"kid": expected_kid}]
):
LOGGER.debug("verifying JWT with source", source=source.slug)
keys = source.oidc_jwks.get("keys", [])
for key in keys:
if key.get("kid") and key.get("kid") != expected_kid:
continue
LOGGER.debug("verifying JWT with key", source=source.slug, key=key.get("kid"))
try:
parsed_key = PyJWK.from_dict(key)
token = decode(
assertion,
parsed_key.key,
algorithms=[key.get("alg")],
algorithms=[key.get("alg")] if "alg" in key else [fallback_alg],
options={
"verify_aud": False,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Hence identification is based on service-accounts, and authentication is based o

An example request can look like this:

```
```http
POST /application/o/token/ HTTP/1.1
Host: authentik.company
Content-Type: application/x-www-form-urlencoded
Expand Down Expand Up @@ -42,7 +42,7 @@ Starting with authentik 2022.6, you can define a JWKS URL/raw JWKS data in OAuth

With this configure, any JWT issued by the configured certificates can be used to authenticate:

```
```http
POST /application/o/token/ HTTP/1.1
Host: authentik.company
Content-Type: application/x-www-form-urlencoded
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ authentik doesn't ship with a default flow for this usecase, so it is recommende

The flow is initiated by sending a POST request to the device authorization endpoint, `/application/o/device/` with the following contents:

```
```http
POST /application/o/device/ HTTP/1.1
Host: authentik.company
Content-Type: application/x-www-form-urlencoded
Expand All @@ -36,7 +36,7 @@ The response contains the following fields:

With this response, the device can start checking the status of the token by sending requests to the token endpoint like this:

```
```http
POST /application/o/token/ HTTP/1.1
Host: authentik.company
Content-Type: application/x-www-form-urlencoded
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,22 @@ return True
9. Open **Flow settings** and choose _azure-ad-enrollment_ as enrollment flow.

Try to login with a **_new_** user. You should see no prompts and the user should have the correct information.

### Machine-to-machine authentication <span class="badge badge--version">authentik 2024.12+</span>

If using [Machine-to-Machine](../../../../add-secure-apps/providers/oauth2/client_credentials.md#jwt-authentication) authentication, some specific steps need to be considered.

When getting the JWT token from Azure AD, set the scope to the Application ID URI, and _not_ the Graph URL; otherwise the JWT will be in an invalid format.

```http
POST /<azure-ad-tenant-id>/oauth2/v2.0/token/ HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&
client_id=<application_client_id>&
scope=api://<application_client_id>/.default&
client_secret=<application_client_secret>
```

The JWT returned from the request above can be used with authentik to exchange it for an authentik JWT.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what this means... You can configure authentik to use the returned JWT (from the request) instead of the auto-generated authentik JWT?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And if we say "can be used" we need to explain how... does one configure it, is it automatic, etc?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those steps are explained in oauth2/client_credentials.md

2 changes: 1 addition & 1 deletion website/docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ module.exports = async function (): Promise<Config> {
prism: {
theme: prismThemes.oneLight,
darkTheme: prismThemes.oneDark,
additionalLanguages: ["python", "diff", "json"],
additionalLanguages: ["python", "diff", "json", "http"],
},
},
presets: [
Expand Down