fix: Apply setAlgo, setSecret and setKeys changes in the Lcobucci provider

Merged
TY
9d ago
+125-4

Summary

The Lcobucci provider builds its signer and Lcobucci\JWT\Configuration once, in the constructor. setAlgo(), setSecret() and setKeys() (inherited from Provider) only update the properties, so after construction:

  • getAlgo() reports the new algorithm, but tokens are still signed and verified with the original one.
  • After setSecret(), tokens are still signed with the original secret, and tokens signed with the old secret still verify.
  • After setKeys(), the new keys are never used.

None of this raises an error, so it is easy to believe a change took effect when it didn't. That matters most when the provider is set up at runtime, for example a different secret per tenant (see #2215, #2234, #2258).

Changes

  • Lcobucci overrides setAlgo(), setSecret() and setKeys(). Each one discards the cached signer and configuration.
  • A new protected config() method rebuilds them on the next encode() or decode(). Because the rebuild is lazy, the setters can be called in any order. For example, setAlgo('RS256') followed by setKeys([...]) works.
  • Switching to an algorithm without the keys it needs now fails when the provider is used (JWTException: Private key is not set.). Before, it silently kept using the old algorithm.
  • Constructor behaviour is unchanged. Providers configured through config/jwt.php behave exactly as before.

Tests

New tests in LcobucciTest:

  • signs with the new algorithm after setAlgo()
  • rejects tokens signed with the previous secret after setSecret()
  • signs with the new secret after setSecret()
  • can switch from HS256 to RS256 with setAlgo() + setKeys()
  • throws when switching to an asymmetric algorithm without keys

All of them fail on 2.x and pass with this change. The full suite passes (240 tests).

Fixes #2215
Fixes #2234
Fixes #2258