spomky-labs / lexik-jose-bridge Goto Github PK
View Code? Open in Web Editor NEWAn Encoder for the LexikJWTAuthenticationBundle that uses web-token/jwt-framework
License: MIT License
An Encoder for the LexikJWTAuthenticationBundle that uses web-token/jwt-framework
License: MIT License
@Spomky hello!
Have you any plans about this repo, in particular to add Symfony 6 support in the near future?
i get the following error message, when running "php bin/console lint:container" in the symfony project:
Invalid definition for service "Jose\Bundle\JoseFramework\DataCollector\CheckerCollector": argument 2 of "Jose\Bundle\JoseFramework\DataCollector\CheckerCollector::addHeaderCheckerManager()" accepts "Jose\Bundle\JoseFramework\Services\HeaderCheckerManager", "Jose\Component\Signature\JWSVerifier" passed.
the linter is part of our deployment process and i need to solve the issue to use the bundle
To Reproduce
i guess install the package and run the linter "php bin/console lint:container"
symfony 4.4.*, php 7.4.1
To allow the user to logout and to be sure that the token is not reused by a malicious application, the bundle should be able to verify that the token is not revoked.
Hello,
We are currently developing an Angular frontend to call our API Symfony where OIDC is used to call REST Controller (with JWT included in the headers).
As the frontend calls several APIs which are secured with the same strategy as done with Symfony, the user (Angular) send a JWT Token with a audience value set by our IDP, let's say "myAngular".
Now the issue with lexik-jose-bridge, if the audience is not set in the configuration, the server_name value is used by default and fall in 401 ERROR because the value "myAngular" <> "serveur_name_value" !
I think using a single value in the configuration (audience) leads to a big issue in case where this API could be called by many clients (SPA, Java, etc...) as the clients cannot have the same audience value.
How to manage to force Symfony API accepting many values under "audience" param ? is any workaround ?
I noticed that the class AudienceChecker from the bundle "web-token/jwt-checker": "^3.2" accepts an array to declare many values (ie. the checkValue method) , so why in the bridge you've change this behavior ?
<?php
declare(strict_types=1);
namespace Jose\Component\Checker;
use function in_array;
use function is_array;
use function is_string;
/**
* This class is a header parameter and claim checker. When the "aud" header parameter or claim is present, it will
* check if the value is within the allowed ones.
*/
final class AudienceChecker implements ClaimChecker, HeaderChecker
{
private const CLAIM_NAME = 'aud';
public function __construct(
private readonly string $audience,
private readonly bool $protectedHeader = false
) {
}
/**
* {@inheritdoc}
*/
public function checkClaim(mixed $value): void
{
$this->checkValue($value, InvalidClaimException::class);
}
/**
* {@inheritdoc}
*/
public function checkHeader(mixed $value): void
{
$this->checkValue($value, InvalidHeaderException::class);
}
public function supportedClaim(): string
{
return self::CLAIM_NAME;
}
public function supportedHeader(): string
{
return self::CLAIM_NAME;
}
public function protectedHeaderOnly(): bool
{
return $this->protectedHeader;
}
private function checkValue(mixed $value, string $class): void
{
if (is_string($value) && $value !== $this->audience) {
throw new $class('Bad audience.', self::CLAIM_NAME, $value);
}
if (is_array($value) && ! in_array($this->audience, $value, true)) {
throw new $class('Bad audience.', self::CLAIM_NAME, $value);
}
if (! is_array($value) && ! is_string($value)) {
throw new $class('Bad audience.', self::CLAIM_NAME, $value);
}
}
}
Thanks
Mehdi
Version(s) affected: v4.0.0
Description
With the provided installation instructions of adding your flex recipes endpoint, Symfony Flex does not honor extra.symfony.require
anymore.
How to reproduce
mkdir skeleton && cd skeleton
composer create-project symfony/skeleton:"5.4.*" .
composer config --json extra.symfony.endpoint '["https://api.github.com/repos/Spomky-Labs/recipes/contents/index.json?ref=main", "flex://defaults"]'
composer update
-> symfony/* packages are updated to latest 6.2.* versionsPossible Solution
Swap the order of extra.symfony.endpoint
so that flex://defaults
is first:
composer config --json extra.symfony.endpoint '["flex://defaults", "https://api.github.com/repos/Spomky-Labs/recipes/contents/index.json?ref=main"]'
composer update
-> symfony/* packages are downgraded to latest 5.4.* versions as expectedThis has the disadvantage that the recipe for spomky-labs/lexik-jose-bridge
will be taken from the recipes contrib repo instead of your custom one. See output after composer req spomky-labs/lexik-jose-bridge
:
Symfony operations: 4 recipes (84563b0c21a9ca4cdcdfc632a8ffa7a7)
- Configuring web-token/jwt-bundle (>=3.0): From github.com/Spomky-Labs/recipes:tree
- Configuring symfony/security-bundle (>=5.3): From github.com/symfony/recipes:main
- Configuring lexik/jwt-authentication-bundle (>=2.5): From github.com/symfony/recipes:main
- WARNING spomky-labs/lexik-jose-bridge (>=2.0): From github.com/symfony/recipes-contrib:main
The recipe for this package comes from the "contrib" repository, which is open to community contributions.
Review the recipe at https://github.com/symfony/recipes-contrib/tree/main/spomky-labs/lexik-jose-bridge/2.0
Do you want to execute this recipe?
[y] Yes
[n] No
[a] Yes for all packages, only for the current installation session
[p] Yes permanently, never ask again for this project
(defaults to n):
Additional context
This is probably a bug in Symfony Flex, as their instructions propose the order as used by you. I could file the bug with them if you would confirm this is not caused by your custom flex recipe endpoint somehow.
Please add support for loading keysets from files, so it's easier to migrate from 1.x
Hello,
I'm facing a latency problem that I didn't figure it out yet, in fact on Bitnami/Symfony:6.3 Docker image it works fine, but if I switch to php:8.2-apache or php:8.2-fpm the REST Controller takes 20 secondes to decode and check signed JWT !
If I disable the bridge and use only Lexik bundle with the public key (JWKS) embedded within the Symfony app there is no latency.
I've already reported the problem (look link below) on Lexik github project but I was doing some tests today and I've discovered something strange with lexik-jose-bridge, if the JWKS is hard coded in the yaml, whatever the value of the key (indexed 0) the bridge validates the JWT, even if change some chars in the key deliberately !
I tested V3.0.2 and 4.0.0 both validate the JWT with a false JWKS of our ADFS.
lexik/LexikJWTAuthenticationBundle#1162
thanks in advance.
Everything is set-up according to docs - but there's no encoder.
bin/console dump:container|grep encoder
[Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException]
You have requested a non-existent service "lexik_jose_bridge.encoder".
Using Symfony 3.2.7
Hello,
Is it possible to define a service which returns the key_set instead of of the %env(LEXIK_JOSE_SIGNATURE_KEYSET)%?
lexik_jose:
key_set: '%env(LEXIK_JOSE_SIGNATURE_KEYSET)%'
Thank
the key_index
setting can be an integer or the key ID (string), but LexikJoseEncoder 's constructor expects it as an integer, so there's no way to use the key ID.
The Jose library now offers an easy way to create a JWKSet and optionally rotate keys after a period of time.
This feature could be used so that the bundle will automatically create a JWKSet for signature operations and, if enabled, encryption depending on algorithms to use.
This feature will remove up to 15 configuration lines:
Because the developers should not care about cryptographic keys and algorithms, then
The bundle could also provide a console command to rotate keys if they are older than a period of time passed as an argument (e.g. bin/console lexik_jose:rotate-keys "7 days"
).
This will also fix #13.
Hello,
When trying to require this bundle in my app, I end up with:
Symfony operations: 17 recipes (b2d1c116c5cf892274952afbca6be32a)
- Configuring symfony/framework-bundle (>=5.2): From github.com/symfony/recipes:master
- Configuring symfony/security-bundle (>=5.1): From github.com/symfony/recipes:master
- Configuring symfony/routing (>=5.1): From github.com/symfony/recipes:master
- Configuring doctrine/annotations (>=1.0): From github.com/symfony/recipes:master
- Configuring sensio/framework-extra-bundle (>=5.2): From github.com/symfony/recipes:master
- Configuring lexik/jwt-authentication-bundle (>=2.5): From github.com/symfony/recipes:master
- Configuring ecphp/api-gw-authenticator (>=dev-master): From auto-generated recipe
- Configuring nyholm/psr7 (>=1.0): From github.com/symfony/recipes:master
- Configuring web-token/jwt-bundle (>=v2.2.8): From auto-generated recipe
- WARNING spomky-labs/lexik-jose-bridge (>=2.0): From github.com/symfony/recipes-contrib:master
The recipe for this package comes from the "contrib" repository, which is open to community contributions.
Review the recipe at https://github.com/symfony/recipes-contrib/tree/master/spomky-labs/lexik-jose-bridge/2.0
Do you want to execute this recipe?
[y] Yes
[n] No
[a] Yes for all packages, only for the current installation session
[p] Yes permanently, never ask again for this project
(defaults to n): yes
- Configuring spomky-labs/lexik-jose-bridge (>=2.0): From github.com/symfony/recipes-contrib:master
- Configuring symfony/console (>=5.1): From github.com/symfony/recipes:master
- Configuring symfony/debug-bundle (>=4.1): From github.com/symfony/recipes:master
- Configuring symfony/monolog-bundle (>=3.3): From github.com/symfony/recipes:master
- Configuring symfony/validator (>=4.3): From github.com/symfony/recipes:master
- Configuring symfony/twig-bundle (>=5.0): From github.com/symfony/recipes:master
- Configuring symfony/web-profiler-bundle (>=3.3): From github.com/symfony/recipes:master
- Configuring twig/extensions (>=1.0): From github.com/symfony/recipes:master
Executing script cache:clear [KO]
[KO]
Script cache:clear returned with error code 1
!!
!! In CheckExceptionOnInvalidReferenceBehaviorPass.php line 86:
!!
!! The service "jose.key_set.lexik_jose_bridge.signature" has a dependency on
!! a non-existent service "Jose\Component\KeyManagement\JKUFactory". Did you m
!! ean this: "Jose\Component\KeyManagement\JWKFactory"?
!!
!!
!!
Script @auto-scripts was called via post-update-cmd
$
While following the installation instructions I encountered a problem with configuration for key_index
, for both signature and encryption.
The key_index
and kid in data generated by Flex recipe do not match in .env and in the yaml config.
Which resulted in
An error occurred while trying to encode the JWT token: Undefined index.
In LexikJoseEncoder.php (line 193)
After changing key_index
to match kid everything works.
The LexikJWTAuthenticationBundle allow custom claims to be set and verified.
Tests should be added to verify those custom claims are correctly set and verified.
Version(s) affected: v3.0.3
Description
in my .env i got:
###> lexik/jwt-authentication-bundle ### JWT_PASSPHRASE=xxxxxxxxxxxxxxxxxxxxx JWT_REFRESH_TTL=2592000 # one month JWT_TTL=86400 # 1 day
in my "spomky_labs_lexik_jose_bridge_bundle.yaml" i got:
ttl: '%env(int:JWT_TTL)%'
when i start a composer install i get:
Invalid type for path "lexik_jose.ttl". Expected "int", but got "string".
How to reproduce
install the package and try to set the TTL in spomky_labs_lexik_jose_bridge_bundle.yaml via a .env var
These 2 services :
spomkylabs_lexik_jose_checker_audience:
class: 'Jose\Component\Checker\AudienceChecker'
arguments:
- '%lexik_jose_bridge.encoder.issuer%'
- true
tags:
- { name: 'jose.checker.claim', alias: 'lexik_jose_audience' }
- { name: 'jose.checker.header', alias: 'lexik_jose_audience' }
and
spomkylabs_lexik_jose_checker_issuer:
class: 'SpomkyLabs\LexikJoseBundle\Checker\IssuerChecker'
arguments:
- '%lexik_jose_bridge.encoder.issuer%'
tags:
- { name: 'jose.checker.claim', alias: 'lexik_jose_issuer' }
- { name: 'jose.checker.header', alias: 'lexik_jose_issuer'
They both receive the same parameter lexik_jose_bridge.encoder.issuer
. This make impossible to have different values for audience
and issuer
.
AFAIK these 2 value can be different. Take for instance JWT token generated by Firebase. According to the doc here https://firebase.google.com/docs/auth/admin/verify-id-tokens the valie for iss
is
https://securetoken.google.com/<audience>
I've already fixed this on my local branch but before opening a PR I just wanna know if you agree that we should have different parameters for audience
and issuer
A global upgrade of this bundle should be done to include Symfony 5 in tests and drop old PHP version if necessary.
Seems like it was required indirectly before but isn't anymore
The lexik-jose-bridge always overrides lexik_jwt_authentication.encoder.service, which isn't necessary.
Since it can be simply set to the required value LexikJoseEncoder::class
, this should not be forced.
But since this would break existing installations, maybe this behaviour could be deprecated, and turned off by a switch?
Maybe something like lexik_jose.disable_automatic_encoder_override: false
?
Background: In prod we have a key set from azure, and with our local tests we want locally created private/public keys. But this isn't possible with the enforced encoder.
As we can see, the config is only loaded from the initial config file, but it would be nice to add support for multi-environment config.
In my case, I want to use a prod environment remote keyset and a local keyset in a development and test environment.
When the signature or the encryption key is updated, valid tokens are rejected because they cannot be decrypted or the signature cannot be verified.
The bundle should keep in a keyset the old keys for few minutes (at least the TTL).
How to reproduce:
Hello,
I use this Bundle to check a JWS sent by my own KeyCloak.
The app workflow can be described like this:
Using a debugger, I found that the exception is thrown by Lexik-Jose-bridge when checking the Token signature (verifySignature
in JWSVerifier
returns false because of $algorithm->verify()
)
For exemple, the config looks like this:
#.env File
###> spomky-labs/lexik-jose-bridge ###
SL_JOSE_BRIDGE_SERVER_NAME=http://keycloak.biometrie.test/auth/realms/Biometrie
SL_JOSE_BRIDGE_SIGNATURE_KEYSET='{"keys":[{"kid":"R0ziM07whcBe1-UcHvimwf1WZQLei3WszfaErj50kVc","kty":"RSA","alg":"RS256","use":"sig","n":"lhqyXCOxPLGHO4TgiJ0SByoCRBUUSFnn6EiBFOpbQPNtuDpAri_IjP3s_S3lL77pHjorTa4EYXNBK-b0bXsNSx6vOzZF04lDc0n-O8O47kBeB1GUm_-pGcn_kWZKHxOKnkhjBlyT2EP2l_Ps_Nzqn4cjocPDqUu61DLpu5AOh-R6kHKGKzkvxAXoi3bQEfpijP0QvHtMH51CTvVmVHPyK8w_fGggH8pXefrw2SOroTd7UbatHNFPpjvER_AmRJQQdF15mL-U4slPo6AxahTiLE6aARpPVuopFVuSgGvImNtzEIxhZAV4agAqKMuNPG_-1LwUVx8Vcg5pCIIY64G1Fw","e":"AQAB","x5c":["MIICmzCCAYMCBgFv5kao7TANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjAwMTI3MDkxMTI4WhcNMzAwMTI3MDkxMzA4WjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCWGrJcI7E8sYc7hOCInRIHKgJEFRRIWefoSIEU6ltA8224OkCuL8iM/ez9LeUvvukeOitNrgRhc0Er5vRtew1LHq87NkXTiUNzSf47w7juQF4HUZSb/6kZyf+RZkofE4qeSGMGXJPYQ/aX8+z83OqfhyOhw8OpS7rUMum7kA6H5HqQcoYrOS/EBeiLdtAR+mKM/RC8e0wfnUJO9WZUc/IrzD98aCAfyld5+vDZI6uhN3tRtq0c0U+mO8RH8CZElBB0XXmYv5TiyU+joDFqFOIsTpoBGk9W6ikVW5KAa8iY23MQjGFkBXhqACooy408b/7UvBRXHxVyDmkIghjrgbUXAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAGoGSh7NLsDUJI/VLAh/GKJL8KdNE/vRT5ix4eVMBj30A62G9e6IxcqNEf+gxsy/WpavPm8dj5KE9LWWJhXq4bqEr2y3E27feYgCjDFZJV5Qbka8I/c1pHxh/y0MI5aa807F6lneYQWottx4vkthqaqM8YA3lWyqINYwy3oZ5pZRCu8U+a0Ijb/A/wFumcw+DWA4zR0Ukn0AGGwLo+UllekHEYPN8YaOtpPTT9db0ecTKEGvJXQCO8LAuvGyOqtdJGBU2EUShfeJYlcJWY2iuuEki6NM54UWRpCfRD8lbfY4qJAMI5pS450Tt4dr5ueavA1zZQ/gDA8v78G/yj0KbP8="],"x5t":"WACX0jnZYYIHH2GbPX1GMdzOy4o","x5t#S256":"B6bMYytBGjflssF_cL0zMIUYIx699Lq72Q8qj8s6sxo"}]}'
###< spomky-labs/lexik-jose-bridge ###
#spomky_labs_lexik_jose_bridge_bundle.yaml
lexik_jose:
ttl: 3600
server_name: '%env(SL_JOSE_BRIDGE_SERVER_NAME)%'
audience: 'account'
key_set: '%env(SL_JOSE_BRIDGE_SIGNATURE_KEYSET)%'
key_index: 0
signature_algorithm: "RS256"
mandatory_claims:
- 'aud'
Example of a token to be verified by the bundle:
eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJfMlE5aW9EM1RtWXBHR19FNVBRQ3JfU0VYNEoxVEFTWmZKczZrZTJ5eFpFIn0.eyJqdGkiOiJmZWVkMDg0Ni0yNDc5LTQ4NWQtYmY1ZC0yYzFhZjQ0ZmJiNzYiLCJleHAiOjE1ODAxMTY4ODksIm5iZiI6MCwiaWF0IjoxNTgwMTE2NTg5LCJpc3MiOiJodHRwOi8va2V5Y2xvYWsuYmlvbWV0cmllLnRlc3QvYXV0aC9yZWFsbXMvQmlvbWV0cmllIiwiYXVkIjoiYWNjb3VudCIsInN1YiI6ImE5NTVmNDNiLTBhOTEtNDU0NS1hOWY2LWU5NjYxZGYzNTkwYyIsInR5cCI6IkJlYXJlciIsImF6cCI6ImJpb21ldHJpZV9jbGllbnQiLCJhdXRoX3RpbWUiOjE1ODAxMTY1ODgsInNlc3Npb25fc3RhdGUiOiIxN2RjYWM3OS1iMjk0LTQ4ZjgtOGY3NS1lZjM4NTM4OThjMzEiLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbImh0dHA6Ly9iaW9tZXRyaWUudGVzdCJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImJpb21ldHJpZV9jbGllbnQiOnsicm9sZXMiOlsiUk9MRV9BRE1JTiJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJuYW1lIjoiVmljdG9yIENhc3Ryby1DSW50YXMiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJ2Y2FzdHJvIiwiZ2l2ZW5fbmFtZSI6IlZpY3RvciIsImZhbWlseV9uYW1lIjoiQ2FzdHJvLUNJbnRhcyIsImVtYWlsIjoidmljdG9yLmNhc3Ryby5jaW50YXNAZ21haWwuY29tIn0.eKjzIPQyxphLuNI5ooEf_u5ReQFAb4t372tBKUwFofYUXxB8JAZ2fyxI3OKGi2jxO8zIjdJM7t8Viin6i9Q1uOWMAgLRUW1SzpcWeQ_9oZVLwjawtquVL2LqxWDQHO1tj9tm4sBjK0SEqaA1l-Q0Zmtt-YKHB_1i7d_u-K2RrciNXMxnTpTqPd5OMN0_xNRV3BKdQqfs2veKFsCRNdq6mXeKrxk6W7GUsI5He6MdJ1R6eGnMlGFhLkiePaUSSYr0K1xehuFr5BawA-1BNeCfPhKwsn95rhWGD5b9WmPNmoV9K6gzmJ4MplzYWL2u0PudPF0SJVDMaMSkxUf4pe0SDA
Hi,
As reported in the issue => Multi-value for audience param #79 , it would be great to support an array of audiences instead of one value, currently the v4.0 supports only one value and it's inconvenient in multi-clients situation (ie. micro-services) as every client has its own audience value.
We appreciate this bundle, it's straightforward and easy to use, keep going guys.
Mehdi
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.