Lexikjwtauthenticationbundle: Unable to create a signed JWT from the given configuration

Created on 16 Jul 2018  路  25Comments  路  Source: lexik/LexikJWTAuthenticationBundle

Hi,

In version 2.4.4 all works fine, but in the 2.5 When I Post to https:/localhost/login_check with valid email and password, and pass to the AuthenticationSuccessHandler.php, i got this error:

{ "error": { "code": 500, "message": "Internal Server Error", "exception": [ { "message": "Unable to create a signed JWT from the given configuration.", "class": "Lexik\\Bundle\\JWTAuthenticationBundle\\Exception\\JWTEncodeFailureException", "trace": [ { "namespace": "", "short_class": "", "class": "", "type": "", "function": "", "file": "/var/www/mumablue/vendor/lexik/jwt-authentication-bundle/Encoder/LcobucciJWTEncoder.php", "line": 41, "args": [] }, { "namespace": "Lexik\\Bundle\\JWTAuthenticationBundle\\Encoder", "short_class": "LcobucciJWTEncoder", "class": "Lexik\\Bundle\\JWTAuthenticationBundle\\Encoder\\LcobucciJWTEncoder", "type": "->", "function": "encode", "file": "/var/www/mumablue/vendor/lexik/jwt-authentication-bundle/Services/JWTManager.php", "line": 64, "args": [ [ "array", { "roles": [ "array", [ [ "string", "STRING" ], [ "string", "ROLE_USER" ] ] ], "username": [ "string", "string2" ] } ] ] }, .......... ] } ] } }

What is the problem?

This is mi configuration file:
Security

security:
encoders:
AppEntityUser: {algorithm: sha512, iterations: 10}

role_hierarchy:
    ROLE_ACCOUNTING: [ROLE_USER]

providers:
    fos_userbundle:
        id: fos_user.user_provider.username_email

firewalls:
    login:
        pattern:  ^/login
        stateless: true
        anonymous: true
        provider: fos_userbundle
        json_login:
            check_path: api_login_check
            username_path: email
            password_path: password
            success_handler: lexik_jwt_authentication.handler.authentication_success
            failure_handler: lexik_jwt_authentication.handler.authentication_failure

    api:
        pattern:   ^/api
        provider: fos_userbundle
        stateless: true
        anonymous: true
        guard:
            authenticators:
                - lexik_jwt_authentication.jwt_token_authenticator

    dev:
        pattern:  ^/(_(profiler|wdt)|css|images|js)/
        security: false

    main:
        pattern: ^/
        anonymous:    true

access_control:
    - { path: ^/api/users, role: IS_AUTHENTICATED_ANONYMOUSLY, methods: [POST]  }
    - { path: ^/api/, roles: [ IS_AUTHENTICATED_FULLY ] } #IS_AUTHENTICATED_FULLY
    - { path: ^/api, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/, roles: [ IS_AUTHENTICATED_ANONYMOUSLY ] }`

Routing
api_login_check: path: /login_check defaults: _format: json methods: [POST]
JWT
lexik_jwt_authentication: private_key_path: '%env(resolve:JWT_PRIVATE_KEY_PATH)%' # required for token creation public_key_path: '%env(resolve:JWT_PUBLIC_KEY_PATH)%' # required for token verification pass_phrase: '%env(resolve:JWT_PASSPHRASE)%' # required for token creation token_ttl: '%env(resolve:JWT_TTL)%'

Bug Needs Review

Most helpful comment

@tarlepp Check that the pass phrase used in the generation of the keys (Verifying - Enter pass phrase for config/jwt/private.pem:) is the same one that is configured in the project JWT settings (JWT_PASSPHRASE).

All 25 comments

Got the problem too, do you got a solution ?
(I tried https://github.com/chalasr/lexik-jwt-authentication-sandbox/tree/flex/config and same problem)

Thanks

I had this issue, though note it wasn't specific to v2.5, this was my first time using the bundle. I've detailed the steps I took to debug and resolve the problem in the hopes that it might help you.

The error message in your title is found in LcobucciJWTEncoder.php and shows up when the $jws->isSigned() condition fails. Signing should be occurring in LcobucciJWSProvider.php and if you dump $e->getMessage() at line 96 you may see something similar to this:

"It was not possible to parse your key, reason: error:0906D06C:PEM routines:PEM_read_bio:no start line"

Chasing the error message again once more may lead you to the validateKey() method of lcobucci/jwt/src/Signer/Rsa.php. Here I found my key was set to false, and to determine why, I dumped the key at the top of this file at the beginning of the createHash() method. With this I noticed the private key was being read from ~/project/config/jwt/private.pem whereas, for my directory structure, it should be using ~/project/app/config/jwt/private.pem.

This turned out to be a relatively simple configuration fix of changing the keys to be read from '%kernel.project_dir%/app/config/jwt/...', which I hadn't noticed when copy-pasting from the docs!

Sorry for the delay, I will look at it tomorrow.

Same problem here.
"require": {
"php": "^7.1.3",
"ext-iconv": "*",
"leaseweb/doctrine-pdo-dblib": "^1.1",
"lexik/jwt-authentication-bundle": "^2.5",
"namshi/jose": "^7.2",
"symfony/console": "^4.0",
"symfony/debug-pack": "^1.0",
"symfony/flex": "^1.0",
"symfony/framework-bundle": "^4.0",
"symfony/lts": "^4@dev",
"symfony/orm-pack": "^1.0",
"symfony/profiler-pack": "^1.0",
"symfony/twig-bundle": "^4.0",
"symfony/var-dumper": "^4.0",
"symfony/web-server-bundle": "^4.0",
"symfony/yaml": "^4.0"
},

I recreate my public and private key and works.
https://github.com/chalasr/lexik-jwt-authentication-sandbox/issues/14

@naxo8628 could you try @regisnew's solution and tell if it fixes the issue?

@chalasr Tried to re-generate keys - no luck with that.

@tarlepp Check that the pass phrase used in the generation of the keys (Verifying - Enter pass phrase for config/jwt/private.pem:) is the same one that is configured in the project JWT settings (JWT_PASSPHRASE).

@falecomjeff ah the pass phrase... my bug is now resolved thanks to you

I get this error when calling

 $this->getContainer()->get('lexik_jwt_authentication.encoder')->encode(['tist'])

from a ContainerAwareCommand.

Some investigation and debugging have shown that the RawKeyLoader instance doesn't even get the keys passed into the constructor. This is probably a regression in key_loader.xml because of https://github.com/lexik/LexikJWTAuthenticationBundle/commit/a6a77189cd9400a4483129bf683955d67e8d8711: the following arguments are no more read from config. So how do I call the encoder directly now?

I've regenerated the public and private keys, but now the question arises, what do I do?

Go back to 2.4.4. That was the only solution for me.

Using version 2.6 of the bundle, make sure in .env file you got you're passphrase added.

So 2.6 is actually breaking change and does not work with Symfony 3.4

@alozytskyi how that ? Please provide a reproducer, it works just fine on my side.

Config:

lexik_jwt_authentication:
    private_key_path: '%jwt_private_key_path%'
    public_key_path:  '%jwt_public_key_path%'
    pass_phrase:      '%jwt_key_pass_phrase%'
    token_ttl:        '%jwt_token_ttl%'

    # extractors:
    token_extractors:
        authorization_header:      # look for a token as Authorization Header
            enabled: true
            prefix:  Bearer
            name:    Authorization

2.4.4 works as expected
2.6.2 throws Unable to create a signed JWT from the given configuration.:

Lexik\Bundle\JWTAuthenticationBundle\Exception\
JWTEncodeFailureException
in vendor/lexik/jwt-authentication-bundle/Encoder/LcobucciJWTEncoder.php (line 41)

Per semver, the config should just work as is

Here is a working application with Symfony 3.4 + lexik-jwt-authentication-bundle 2.6 and your configuration: https://github.com/chalasr/lexikjwt-2.6-sf-3.4
You can try to downgrade the bundle to 2.4.4, it works as well.

My guess is that when upgrading, the recipe has been updated and your passphrase was regenerated in your .env file, which means it doesn't match with your keys anymore. Unless I'm mistaken there is no BC break here, only some configuration issue which may be improved on the bundle recipe, nothing to do here. Regenerate the keys in your project, update your passphrase in the bundle config accordingly and it should work as expected.

@chalasr my app was started back in the times when .env files weren't supported, and .env support is yet to be integrated, if at all necessary.

So I guess the problem is with apps that were upgraded from previous versions of symfony without enabling .env support?

From your error looks like the keys are not well configured, regenerate them and make sure your passphase is declared, can't help more, using symfony 4.2 with full .env suport.

From your error looks like the keys are not well configured, regenerate them and make sure your passphase is declared, can't help more, using symfony 4.2 with full .env suport.

So why does downgrading to 2.4.4 works, whereas upgrading to 2.6+ does not? Without changing anything in the configs?

I have the same problem. Getting the error message: "Unable to create a signed JWT from the given configuration."

I have regenerate my keys etc. None of that is working.
But I found the cause / work-a-round.

My lexik_jwt_authentication.yaml is the follow:
lexik_jwt_authentication: private_key_path: '%env(resolve:JWT_SECRET_KEY)%' public_key_path: '%env(resolve:JWT_PUBLIC_KEY)%' pass_phrase: '%env(resolve:JWT_PASSPHRASE)%'

If I put my passphrase hardcode here instead of the env variable it works.

my error with this was that I was using make command and it was not loading the correct .env file to read that pass_phrase part correctly. And in that point that pass_phrase was only thing that user could configure in my app.

After that I changed my application behaviour to keep those all three parameters in .env file(s) OR actual environment variables + made necessary changes to my Makefile to read those properly. And for that part following should help you.

ifndef APPLICATION_CONFIG
    # Determine which .env file to use
    ifneq ("$(wildcard .env.local)","")
        include .env.local
    else
        include .env
    endif
endif

# Define used JWT keys paths and passphrase
JWT_PUBLIC_KEY=$$(echo | jq -r .JWT_PUBLIC_KEY ${APPLICATION_CONFIG})
JWT_SECRET_KEY=$$(echo | jq -r .JWT_SECRET_KEY ${APPLICATION_CONFIG})
JWT_PASSPHRASE=$$(echo | jq -r .JWT_PASSPHRASE ${APPLICATION_CONFIG})

.DEFAULT_GOAL := help
.PHONY: help
help:
    @grep -E '^[a-zA-Z-]+:.*?## .*$$' Makefile | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "%-27s %s\n", $$1, $$2}'

###> lexik/jwt-authentication-bundle ###
OPENSSL_BIN := $(shell which openssl)
generate-jwt-keys: ## Generates JWT auth keys
ifndef OPENSSL_BIN
    $(error "Unable to generate keys (needs OpenSSL)")
endif
    @echo "\033[32mGenerating RSA keys for JWT\033[39m"
    @mkdir -p config/jwt
    @rm -f ${JWT_SECRET_KEY}
    @rm -f ${JWT_PUBLIC_KEY}
    @openssl genrsa -passout pass:${JWT_PASSPHRASE} -out ${JWT_SECRET_KEY} -aes256 4096
    @openssl rsa -passin pass:${JWT_PASSPHRASE} -pubout -in ${JWT_SECRET_KEY} -out ${JWT_PUBLIC_KEY}
    @chmod 664 ${JWT_SECRET_KEY}
    @chmod 664 ${JWT_PUBLIC_KEY}
    @echo "\033[32mRSA key pair successfully generated\033[39m"
###< lexik/jwt-authentication-bundle ###

And with that I could just define that APPLICATION_CONFIG environment variable in production environment to skip that .env file usage totally.

This setup helped me within this issue - I hope that this will also help some other people who is facing this same...

Closing as this seems to be a misconfiguration.

Just an additional note for those who would face the same error message. You can also have it if the paths to your keys are incorrect, so this is the very first thing to verify.

If like me someone uses php8, there is a compatibility issue with the library lcobucci/jwt,, related to this commit https://github.com/lcobucci/jwt/commit/be0f2f94c4bd24a2c69a6af9e5949848c29a0921. You just need to upgrade the library

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Walkoss picture Walkoss  路  5Comments

evaldoprestes picture evaldoprestes  路  3Comments

AlexDupreWeb picture AlexDupreWeb  路  4Comments

pbalan picture pbalan  路  5Comments

Zempheroth picture Zempheroth  路  4Comments