0

I am trying to upgrade the Lexic/JWTAuthenticationBundle from version 1.7 to 2.14. (This is in support of our upgrade of the Symfony bundle from version 3 to 4, and eventually 5).

Some of our code makes API queries with the token as a query parameter (meaning in the URL). This stopped working after we upgraded. Calls that put the token into curl request headers still work.

Here is an example of a call that works on the old setup, but not the new ($token is supplied by a previous call to our API to login):

$curl_opts = array(
  \CURLOPT_URL            => $our_url . "?bearer=" . $token;
  \CURLOPT_SSL_VERIFYPEER => false,
  \CURLOPT_SSL_VERIFYHOST => false,
  \CURLOPT_RETURNTRANSFER => 1,
  \CURLOPT_USERAGENT      => 'cURL Request',
  \CURLOPT_CONNECTTIMEOUT => 5,
  \CURLOPT_TIMEOUT        => 10, 
  \CURLOPT_HEADER         => false, 
  \CURLOPT_CUSTOMREQUEST  => GET,
  \CURLOPT_POSTFIELDS     => '',
  \CURLOPT_HTTPHEADER     => array(
                                'Content-Type: application/x-www-form-urlencoded',
                                'Content-Length: ' . 0
                             ),
);
$curl = curl_init();
curl_setopt_array($curl, $curl_opts);
$data = curl_exec($curl);
curl_close($curl);

This returns a 500 error, and this error message is logged:

request.CRITICAL: Uncaught PHP Exception Lexik\Bundle\JWTAuthenticationBundle\Exception\JWTDecodeFailureException: "Invalid JWT Token" at /oursymfony/vendor/lexik/jwt-authentication-bundle/Encoder/LcobucciJWTEncoder.php line 53 {"exception":"[object] (Lexik\\Bundle\\JWTAuthenticationBundle\\Exception\\JWTDecodeFailureException(code: 0): Invalid JWT Token at /oursymfony/vendor/lexik/jwt-authentication-bundle/Encoder/LcobucciJWTEncoder.php:53, Lcobucci\\JWT\\Token\\InvalidTokenStructure(code: 0): The JWT string must have two dots at /var/www/nest/core/vendor/lcobucci/jwt/src/Token/InvalidTokenStructure.php:13)"} []

If I make the same call, but add the token in the curl headers instead of the URL, the call works.

I believe we have correctly configured this to work. Here is our configuration:

lexik_jwt_authentication:
    private_key_path:    ""
    public_key_path:     ""
    # ...
    token_extractors:
        authorization_header:       # check token in Authorization Header
            enabled: true
            prefix:  Bearer         # case-sensitive...can also be an arbitrary string ('SCStoken')
        cookie:                     # check token in a cookie
            enabled: true
            name:    BEARER
        query_parameter:            # check token in query string parameter
            enabled: true
            name:    bearer

I looked a bit at the code where the error is thrown, and noticed that on the broken call, the token is empty, but on the working call it's there.

2 Answers2

0

It seems to me that the token needs to be sent in the request header

  CURLOPT_HTTPHEADER => array(
    'Content-Type: application/x-www-form-urlencoded',
    'Authorization: Bearer you-token'
  ),
emrdev
  • 2,155
  • 3
  • 9
  • 15
  • Thanks. Your suggestion would work, but because we have a large code base calling the API, it will be difficult to find all of the broken calls. However, if I can't get this to work, that is what I will need to do. – Karen Delehanty Feb 17 '22 at 16:53
  • Just test on any one request. I don't know how it was in version 1.7, but I'm using version 2 and it works for me. No other way. Your lexik_jwt_authentication configuration says that the token is expected in the request from the header – emrdev Feb 17 '22 at 17:08
0

This will probably not be helpful to other people, but I believe the source of the issue was a class written by our team that interacted with the other security components including the lexik_jwt_authentication plugin.

I don't understand this, but prior to the upgrade, our code evaluated tokens passed in the header, and lexik evaluated tokens passed in the header or the query parameter. After the upgrade, the lexik code didn't evaluate tokens. (The code was still there, it just wasn't reached. Possibly because of how our code interacted with it). However, I was able to modify our code to handle both types of evaluation.