swarm-authelia: let a client declare its token-endpoint auth method
tuwunel authenticates at the token endpoint with the secret in the POST body. Authelia enforces the method a client is REGISTERED with rather than accepting whichever one arrives, and its default is client_secret_basic — so the matrix login completed, consent was granted, and the very last hop failed: Client authentication failed ... The request was determined to be using token_endpoint_auth_method client_secret_post, however the OAuth 2.0 client registration does not allow this method. The failure names neither the secret nor the redirect, and it lands three layers from its cause, which is why it read as a credential problem. Adds a per-client tokenEndpointAuthMethod, null by default so every existing client keeps authelia default (forgejo authenticates with basic and is unaffected), and sets client_secret_post on the matrix client only.
This commit is contained in:
parent
b4b4967ec9
commit
8c51e37804
2 changed files with 39 additions and 0 deletions
|
|
@ -665,6 +665,13 @@ in
|
|||
id = cfg.sso.clientId;
|
||||
description = "HyperHive matrix";
|
||||
redirectUris = [ ssoCallbackUrl ];
|
||||
# tuwunel authenticates at the token endpoint by putting the
|
||||
# secret in the POST body. Authelia enforces the *registered*
|
||||
# method rather than accepting whichever one arrives, and its
|
||||
# default is `client_secret_basic` — so without this the browser
|
||||
# flow completes, consent is granted, and the very last hop fails
|
||||
# with a 401 that names neither the secret nor the redirect.
|
||||
tokenEndpointAuthMethod = "client_secret_post";
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -144,6 +144,9 @@ let
|
|||
printf -- " client_secret: '%s'\n" "$(cat ${lib.escapeShellArg "${clientsDir}/${c.id}.digest"})"
|
||||
printf -- ' authorization_policy: one_factor\n'
|
||||
''
|
||||
+ lib.optionalString (c.tokenEndpointAuthMethod != null) ''
|
||||
printf -- ' token_endpoint_auth_method: %s\n' ${lib.escapeShellArg c.tokenEndpointAuthMethod}
|
||||
''
|
||||
+ (
|
||||
if c.kind == "machine" then
|
||||
''
|
||||
|
|
@ -417,6 +420,35 @@ in
|
|||
rather than silently ignored.
|
||||
'';
|
||||
};
|
||||
|
||||
tokenEndpointAuthMethod = lib.mkOption {
|
||||
type = lib.types.nullOr (
|
||||
lib.types.enum [
|
||||
"client_secret_basic"
|
||||
"client_secret_post"
|
||||
"client_secret_jwt"
|
||||
"private_key_jwt"
|
||||
"none"
|
||||
]
|
||||
);
|
||||
default = null;
|
||||
example = "client_secret_post";
|
||||
description = ''
|
||||
How this client proves its identity at the token
|
||||
endpoint. `null` leaves authelia on its own default
|
||||
(`client_secret_basic`), which is what every client that
|
||||
does not say otherwise gets.
|
||||
|
||||
Set it when the relying party's implementation differs,
|
||||
because authelia enforces the registered method rather
|
||||
than accepting whatever arrives. tuwunel sends
|
||||
`client_secret_post`, and against a client registered for
|
||||
basic the result is a 401 from `/api/oidc/token` **after
|
||||
a successful consent** — the login looks like it worked
|
||||
right up to the last hop, and neither the redirect nor
|
||||
the secret is at fault.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue