Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
379 views
in Technique[技术] by (71.8m points)

How to verify JWT with JWK - PHP

I am working on Identity server and OpenId connect and since I need to do the implementation in a more dynamic manner and on multiple microservices in different languages, I am trying to understand the flow and doing the implementation with different stacks without depending on the client SDKs provided by the particular Identity server provider we are using. (in production, most likely, we will use some already built libs but my intention now is to grasp the concept of verification from ground up)

Now I am trying to simulate a case where we already have the access and id tokens and they are sent to a simple REST PHP function, and:

  • Do verification of JWT signature
  • Expiration check on the token
  • Validation of Scope & Audience
  • Pass username back to the frontend

(not relevant but I generated the access_token with Authorisation code flow -> PKCE)

This is my verification flow, I am using jose-php packages:

# public key
$components = array(
    'kty' => 'RSA',
    'e' => 'AQAB',
    'n' => 'x9vNhcvSrxjsegZAAo4OEuo...'
);


$public_key= JOSE_JWK::decode($components);



$jwt_string = 'eyJ...'; // Access_token
$jws = JOSE_JWT::decode($jwt_string);
$result = $jws->verify($public_key, 'RS256');

However, this returns undefined for $result. I am debugging other parts of the PHP script, and I will share my result with everyone here once I find a fix but I think there is a better way (not with provider exclusive client SDKs) to do this flow and there is a high chance that I am missing something.

If anyone has a background with JWT token verification with PHP for identity server, It will be really great if you can share any better alternative or suggestions to do this here

Thank you in advance :)

question from:https://stackoverflow.com/questions/66063172/how-to-verify-jwt-with-jwk-php

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is an answer for anyone who seeks a simple verification middleware for jwks, might not be ideal for production!!! You are more than welcome to suggest a better solution :)

I switched to firebase/php-jwt as it is more convenient and straightforward to use and it was fairly easier to go quickly through its code and it does not return undefined anymore. Now the middleware code for validation looks like below:

$jwks?=?['keys'?=>?[[], []];?

//?JWK::parseKeySet($jwks)?returns?an?associative?array?of?**kid**?to?private

//?key.?Pass?this?as?the?second?parameter?to?JWT::decode. 
// Instead of RS256 use your own algo
// $data can return error so wrap it in try catch and do as you desire afterward
$data=?(array)?JWT::decode("YOUR_ACCESS_TOKEN",?JWK::parseKeySet($jwks),?['RS256',?'RS256']);

For those who are willing to test a sample encoding and decoding process, feel free to use the private key and public key below: (Credit to firebase documentation with a bit of tweaking on my side to convert it to a simple Laravel controller)

<?php

namespace?AppHttpControllers;

use?IlluminateHttpRequest;

use?FirebaseJWTJWT;

use?FirebaseJWTJWK;

use?IlluminateSupportFacadesHttp;

class?JWTValidation?extends?Controller

{

????public?function?bundle(){

????????

????????$privateKey?=?<<<EOD

????????-----BEGIN?RSA?PRIVATE?KEY-----

????????MIICXAIBAAKBgQC8kGa1pSjbSYZVebtTRBLxBz5H4i2p/llLCrEeQhta5kaQu/Rn

????????vuER4W8oDH3+3iuIYW4VQAzyqFpwuzjkDI+17t5t0tyazyZ8JXw+KgXTxldMPEL9

????????5+qVhgXvwtihXC1c5oGbRlEDvDF6Sa53rcFVsYJ4ehde/zUxo6UvS7UrBQIDAQAB

????????AoGAb/MXV46XxCFRxNuB8LyAtmLDgi/xRnTAlMHjSACddwkyKem8//8eZtw9fzxz

????????bWZ/1/doQOuHBGYZU8aDzzj59FZ78dyzNFoF91hbvZKkg+6wGyd/LrGVEB+Xre0J

????????Nil0GReM2AHDNZUYRv+HYJPIOrB0CRczLQsgFJ8K6aAD6F0CQQDzbpjYdx10qgK1

????????cP59UHiHjPZYC0loEsk7s+hUmT3QHerAQJMZWC11Qrn2N+ybwwNblDKv+s5qgMQ5

????????5tNoQ9IfAkEAxkyffU6ythpg/H0Ixe1I2rd0GbF05biIzO/i77Det3n4YsJVlDck

????????ZkcvY3SK2iRIL4c9yY6hlIhs+K9wXTtGWwJBAO9Dskl48mO7woPR9uD22jDpNSwe

????????k90OMepTjzSvlhjbfuPN1IdhqvSJTDychRwn1kIJ7LQZgQ8fVz9OCFZ/6qMCQGOb

????????qaGwHmUK6xzpUbbacnYrIM6nLSkXgOAwv7XXCojvY614ILTK3iXiLBOxPu5Eu13k

????????eUz9sHyD6vkgZzjtxXECQAkp4Xerf5TGfQXGXhxIX52yH+N2LtujCdkQZjXAsGdm

????????B2zNzvrlgRmgBrklMTrMYgm1NPcW+bRLGcwgW2PTvNM=

????????-----END?RSA?PRIVATE?KEY-----

????????EOD;

????????$publicKey?=?<<<EOD

????????-----BEGIN?PUBLIC?KEY-----

????????MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8kGa1pSjbSYZVebtTRBLxBz5H

????????4i2p/llLCrEeQhta5kaQu/RnvuER4W8oDH3+3iuIYW4VQAzyqFpwuzjkDI+17t5t

????????0tyazyZ8JXw+KgXTxldMPEL95+qVhgXvwtihXC1c5oGbRlEDvDF6Sa53rcFVsYJ4

????????ehde/zUxo6UvS7UrBQIDAQAB

????????-----END?PUBLIC?KEY-----

????????EOD;

????????

????????$payload?=?array(

????????????"iss"?=>?"example.org",

????????????"aud"?=>?"example.com",

????????????"iat"?=>?1356999524,

????????????"nbf"?=>?1357000000

????????);

????????

????????$jwt?=?JWT::encode($payload,?$privateKey,?'RS256');

????????//echo?"Encode:
"?.?print_r($jwt,?true)?.?"
";

????????

????????$decoded?=?JWT::decode($jwt,?$publicKey,?array('RS256'));

????????

????????/*

?????????NOTE:?This?will?now?be?an?object?instead?of?an?associative?array.?To?get

?????????an?associative?array,?you?will?need?to?cast?it?as?such:

????????*/

????????

????????$decoded_array?=?(array)?$decoded;

????????return?response()->json(['jwt'?=>?$jwt,?'decoded'?=>?$decoded]);

????????//echo?"Decode:
"?.?print_r($decoded_array,?true)?.?"
";

????}
}

Now back to my first question again :)

In case that I validate the key with the help of this library as the first piece of the code, am I exposing any vulnerability? or will it be a time-consuming task in long run to maintain a custom verification flow like this?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...