Skip to content

Align with backchannel logout OIDC spec#1432

Merged
julien-nc merged 6 commits intonextcloud:mainfrom
Spitfireap:fix/1430-backchannel-oidc-spec
May 4, 2026
Merged

Align with backchannel logout OIDC spec#1432
julien-nc merged 6 commits intonextcloud:mainfrom
Spitfireap:fix/1430-backchannel-oidc-spec

Conversation

@Spitfireap
Copy link
Copy Markdown
Contributor

@Spitfireap Spitfireap commented Apr 28, 2026

Current behaviour

The response of BackChannel logout seems to be missing the Cache-Control header (spec).

The BC logout validation is also missing exp token validation (not expired) and iss validation (equals to issuer in discovery endpoint) per Backchannel logout token validation spec and ID Token validation spec

Changes

  • Removed an unused variable from getBackchannelLogoutErrorResponse ($throttleMetadata)
  • Increased the severity of the logging when a Backchannel logout fails
  • Added the Cache-Control header in the backchannel logout response
  • Added a verification for the exp and iss claim
  • Check that all required tokens by the spec are there

@Spitfireap Spitfireap force-pushed the fix/1430-backchannel-oidc-spec branch from da506df to 149ded7 Compare April 28, 2026 18:33
@Spitfireap
Copy link
Copy Markdown
Contributor Author

@julien-nc not entirely sure about the change for the error logging.
I think the severity should be increased since it might be a security issue. The thing is : could these be triggered by a random idp and in that case we should perhaps be cautious about using error or it requires the idp to be verified so error would be well suited ?

Copy link
Copy Markdown
Member

@julien-nc julien-nc left a comment

Choose a reason for hiding this comment

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

Nice, thanks. Let's get #1431 in first, then you can rebase and adjust this one.

Comment thread lib/Controller/LoginController.php Outdated
Comment thread lib/Controller/LoginController.php
@Spitfireap Spitfireap force-pushed the fix/1430-backchannel-oidc-spec branch 2 times, most recently from 0478e3e to 05b982d Compare April 29, 2026 12:07
@Spitfireap
Copy link
Copy Markdown
Contributor Author

Spitfireap commented Apr 29, 2026

Added some more alignment with the spec (exp + 1 iss validation step).

Was wondering if we should verify that jti and iat claims are there as well (since they are required) or am I overdoing it ?

Copy link
Copy Markdown
Member

@julien-nc julien-nc left a comment

Choose a reason for hiding this comment

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

Hey. #1431 is merged. Sorry there seems to be a small conflict with your branch. You can rebase on main or just merge main in your branch to resolve the conflict.

Was wondering if we should verify that jti and iat claims are there as well...

Yeah sure, let's keep it simple: It's enough to check if those token attributes are defined.

Comment thread lib/Controller/LoginController.php Outdated
['iss_should_be_set' => true]
true
);
} elseif ($iss !== $discovery['issuer']) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

$iss is not defined at this point.

Comment thread lib/Controller/LoginController.php Outdated
Comment on lines +1026 to +1027
$this->logger->error('Backchannel logout error. ' . $error . ' ; ' . $description .
'. This is likely an IdP issue.');
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
$this->logger->error('Backchannel logout error. ' . $error . ' ; ' . $description .
'. This is likely an IdP issue.');
$this->logger->error('Backchannel logout error. ' . $error . ' ; ' . $description .
'. This is likely an IdP issue.', ['metadata' => $metadata]);

You could keep the metadata param (which can be renamed) and include it in the logs so the information is more precise than the $isLikelyIdpSide boolean. Wdyt?

Comment thread lib/Controller/LoginController.php Outdated
['multiple_sessions_found' => $sid]
);
$this->logger->warning('[BackchannelLogout] Multiple OIDC sessions retrieved (sid+sub+iss). ' .
'This should not happen. Please check that you have created your DB indexes')
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Missing ;

@Spitfireap
Copy link
Copy Markdown
Contributor Author

Hey. #1431 is merged. Sorry there seems to be a small conflict with your branch. You can rebase on main or just merge main in your branch to resolve the conflict.

Was wondering if we should verify that jti and iat claims are there as well...

Yeah sure, let's keep it simple: It's enough to check if those token attributes are defined.

Working on May the 1st are you :p ?
I'll push the rebase and some rework, then test it a bit on my instance. I'll ping you when it's ready.

@julien-nc
Copy link
Copy Markdown
Member

Working on May the 1st are you :p ?

Checking your github notifications on May 1st? 😁

Yeah for a weird reason I'm working today. I can tell you on a private channel if you're curious.

I'll push the rebase and some rework, then test it a bit on my instance. I'll ping you when it's ready.

Nice! Thank you for the enthusiasm. No rush though, feel free to take the public holiday 😉

@Spitfireap Spitfireap force-pushed the fix/1430-backchannel-oidc-spec branch from f0865f4 to f209fb6 Compare May 1, 2026 22:54
@Spitfireap Spitfireap marked this pull request as draft May 1, 2026 23:24
@Spitfireap Spitfireap force-pushed the fix/1430-backchannel-oidc-spec branch from f209fb6 to d9bf10b Compare May 3, 2026 19:13
@Spitfireap
Copy link
Copy Markdown
Contributor Author

@julien-nc should be ready.
Funny thing : LemonLDAP implementation of OP is actually not aligned with the spec (exp token missing).
So although my initial issue is fixed, I still get the error message after this PR. I don't think we should let it pass anyway though. Wdyt ?

@Spitfireap Spitfireap marked this pull request as ready for review May 3, 2026 19:18
@Spitfireap
Copy link
Copy Markdown
Contributor Author

Note : this means that LemonLDAP's users won't be logged out anymore in case of OP initiated logout...
This might be a security issue so idk if we should add a way of bypassing it or add a warning of some sort in the README for instance

Comment thread lib/Controller/LoginController.php Outdated
string $description,
array $throttleMetadata = [],
array $metadata = [],
string $severity = 'warning',
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
string $severity = 'warning',
string $severity = \Psr\Log\LogLevel::WARNING,

Comment thread lib/Controller/LoginController.php Outdated
return $this->getBackchannelLogoutErrorResponse(
'could not reach provider endpoint',
'URL: ' . $provider->getDiscoveryEndpoint() . 'was not reachable',
severity: 'error',
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
severity: 'error',
severity: \Psr\Log\LogLevel::ERROR,

Comment thread lib/Controller/LoginController.php Outdated
'invalid audience',
'The audience of the logout token does not match the provider',
['invalid_audience' => $logoutTokenPayload->aud]
['extra_context' => 'Probably is an IdP side issue', 'aud' => $aud]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
['extra_context' => 'Probably is an IdP side issue', 'aud' => $aud]
['extra_context' => 'Probably is an IdP side issue', 'aud' => $aud, 'client_id' => $clientId]

Comment thread lib/Controller/LoginController.php Outdated
Comment on lines +944 to +945
$iss = $logoutTokenPayload->iss;
if ($iss !== $discovery['issuer']) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
$iss = $logoutTokenPayload->iss;
if ($iss !== $discovery['issuer']) {
$iss = $logoutTokenPayload->iss;
$discoveryIssuer = $discovery['issuer'] ?? '';
if ($iss !== $discoveryIssuer) {

Comment thread lib/Controller/LoginController.php Outdated
[
'extra_context' => 'Probably is an IdP side issue',
'iss' => $iss,
'issuer' => $discovery['issuer']
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
'issuer' => $discovery['issuer']
'issuer' => $discoveryIssuer,

Comment thread lib/Controller/LoginController.php Outdated
[
'extra_context' => 'Probably is an IdP side issue',
'exp' => $logoutTokenPayload->exp,
'current_time' => $this->timeFactory->getTime()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
'current_time' => $this->timeFactory->getTime()
'current_time' => $this->timeFactory->getTime(),

Comment thread lib/Controller/LoginController.php Outdated
$sub === null ? 'Multiple sessions were found with this (sid,iss)' : 'Multiple sessions were found with this (sid,sub,iss)',
['multiple_sessions_found' => $sid]
$this->logger->warning('[BackchannelLogout] Multiple OIDC sessions retrieved (sid+sub+iss). '
. 'This should not happen. Please check that you have created your DB indexes'
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
. 'This should not happen. Please check that you have created your DB indexes'
. 'This should not happen.'

Missing indexes don't change anything to this. It cannot make the request return multiple results.

@julien-nc
Copy link
Copy Markdown
Member

I don't think we should let it pass anyway though. Wdyt ?

I think it's fine to let this pass if the token expiration is not defined. So:

  • If the exp is defined, we validate it
  • If it's not defined, we just ignore

Sounds good to you?

Spitfireap added 5 commits May 4, 2026 12:59
refurbished $throttleMetadata not used since 9b5d6c6

Signed-off-by: Spitap <dev@asdrip.fr>
Signed-off-by: Spitap <dev@asdrip.fr>
Signed-off-by: Spitap <dev@asdrip.fr>
Signed-off-by: Spitap <dev@asdrip.fr>
Signed-off-by: Spitap <dev@asdrip.fr>
@Spitfireap
Copy link
Copy Markdown
Contributor Author

I don't think we should let it pass anyway though. Wdyt ?

I think it's fine to let this pass if the token expiration is not defined. So:

* If the exp is defined, we validate it

* If it's not defined, we just ignore

Sounds good to you?

If you say so. Although it is a clear deviation from the spec I think since it is REQUIRED, and we ought to verify it as we would do in the code function...

For instance, had LemonLDAP not forget to make the exp claim required in its RP implementation, the OP would get the 400 error pretty much as current fix.

So do I make it optional ?

@Spitfireap Spitfireap force-pushed the fix/1430-backchannel-oidc-spec branch from d9bf10b to 5576b98 Compare May 4, 2026 11:11
deliberately removed. See nextcloud#1432

Signed-off-by: Spitap <dev@asdrip.fr>
Copy link
Copy Markdown
Member

@julien-nc julien-nc left a comment

Choose a reason for hiding this comment

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

Let's get this in while it implements the RFC. We can discuss the missing exp later.

@julien-nc julien-nc merged commit c9e1f86 into nextcloud:main May 4, 2026
45 checks passed
@julien-nc
Copy link
Copy Markdown
Member

Thanks a lot for the adjustments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants