diff --git a/authentik/providers/oauth2/views/token.py b/authentik/providers/oauth2/views/token.py index aa3a9fcc2657..4ce13a6bcac4 100644 --- a/authentik/providers/oauth2/views/token.py +++ b/authentik/providers/oauth2/views/token.py @@ -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, }, diff --git a/website/docs/add-secure-apps/providers/oauth2/client_credentials.md b/website/docs/add-secure-apps/providers/oauth2/client_credentials.md index 5fd11ad2eee5..18f7b0df60e2 100644 --- a/website/docs/add-secure-apps/providers/oauth2/client_credentials.md +++ b/website/docs/add-secure-apps/providers/oauth2/client_credentials.md @@ -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 @@ -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 diff --git a/website/docs/add-secure-apps/providers/oauth2/device_code.md b/website/docs/add-secure-apps/providers/oauth2/device_code.md index 0fcd63bc596a..b7c2763eecde 100644 --- a/website/docs/add-secure-apps/providers/oauth2/device_code.md +++ b/website/docs/add-secure-apps/providers/oauth2/device_code.md @@ -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 @@ -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 diff --git a/website/docs/users-sources/sources/social-logins/azure-ad/index.md b/website/docs/users-sources/sources/social-logins/azure-ad/index.md index e6e5c4054c76..e90db1feb255 100644 --- a/website/docs/users-sources/sources/social-logins/azure-ad/index.md +++ b/website/docs/users-sources/sources/social-logins/azure-ad/index.md @@ -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 authentik 2024.12+ + +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 //oauth2/v2.0/token/ HTTP/1.1 +Host: login.microsoftonline.com +Content-Type: application/x-www-form-urlencoded + +grant_type=client_credentials& +client_id=& +scope=api:///.default& +client_secret= +``` + +The JWT returned from the request above can be used with authentik to exchange it for an authentik JWT. diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index f52268aa2a23..572e429b1dad 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -80,7 +80,7 @@ module.exports = async function (): Promise { prism: { theme: prismThemes.oneLight, darkTheme: prismThemes.oneDark, - additionalLanguages: ["python", "diff", "json"], + additionalLanguages: ["python", "diff", "json", "http"], }, }, presets: [