A wrong OIDC issuer, which is the usual IdP setup mistake, sends the
user back to the login page with a bare "Authentication failed". The
callback has a handler that explains it ("OIDC issuer validation failed.
Verify your discovery URL and IdP issuer/external URL configuration."),
and it never runs.
Authlib validates the ID token with joserfc now, so the error that comes
out of `authorize_access_token()` is `joserfc.errors.InvalidClaimError`.
The handler catches the one in `authlib.jose.errors`, which is a
different class with a different base, so the isinstance check is False.
I confirmed it by validating a real `CodeIDToken` with a wrong `iss` on
Authlib 1.9.1. I haven't run it against a live IdP.
The existing tests passed because they raise the old class from a mock.
The new one raises the error from a real `CodeIDToken`, and it fails on
the old import with `'Authentication failed'` in place of the guidance.
Two small things come with it:
- The new class names its attribute `claim` where the old one used
`claim_name`, so that read changes.
- `authlib.jose` is deprecated in favour of joserfc and Authlib's own
warning says it goes in 2.0. This was the only place Shelfmark used it,
so the import moving also takes us off the module that is going away.
joserfc is already installed as an Authlib requirement, so I added it to
`pyproject.toml` (`>=1.6.8`, Authlib's own floor) and the lock gets the
one entry. No new package.
Ruff, basedpyright and the backend suite pass (5424 passed).