22
33namespace Pdsinterop \Solid \Auth \Utils ;
44
5- use Lcobucci \JWT \Parser ;
6- use Lcobucci \JWT \Signer \Key ;
7- use Lcobucci \JWT \ValidationData ;
5+ use Lcobucci \JWT \Configuration ;
6+ use Lcobucci \Clock \SystemClock ;
7+ use DateTimeImmutable ;
8+ use DateInterval ;
9+ use Lcobucci \JWT \Signer \Key \InMemory ;
10+ use Lcobucci \JWT \Signer \Rsa \Sha256 ;
11+ use Lcobucci \JWT \Validation \Constraint \LooseValidAt ;
12+
813use Jose \Component \Core \JWK ;
914use Jose \Component \Core \Util \ECKey ;
1015use Jose \Component \Core \Util \RSAKey ;
1116
1217class DPop {
1318 public function getWebId ($ request ) {
1419 $ auth = explode (" " , $ request ->getServerParams ()['HTTP_AUTHORIZATION ' ]);
15- $ jwt = $ auth [1 ];
20+ $ jwt = $ auth [1 ] ?? false ;
1621
1722 if (strtolower ($ auth [0 ]) == "dpop " ) {
1823 $ dpop = $ request ->getServerParams ()['HTTP_DPOP ' ];
@@ -37,22 +42,22 @@ public function getDpopKey($dpop, $request) {
3742 //error_log("11");
3843 $ this ->validateDpop ($ dpop , $ request );
3944 //error_log("22");
40-
41- $ parser = new \Lcobucci \JWT \Parser ();
45+
4246 // 1. the string value is a well-formed JWT,
43- $ dpop = $ parser ->parse ($ dpop );
44- $ jwk = $ dpop ->getHeader ("jwk " );
47+ $ jwtConfig = $ configuration = Configuration::forUnsecuredSigner ();
48+ $ dpop = $ jwtConfig ->parser ()->parse ($ dpop );
49+ $ jwk = $ dpop ->headers ()->get ("jwk " );
4550 //error_log(print_r($jwk, true));
4651
47- return $ jwk-> kid ;
52+ return $ jwk[ ' kid ' ];
4853 }
4954
5055 private function validateJwtDpop ($ jwt , $ dpopKey ) {
51- $ parser = new \ Lcobucci \ JWT \ Parser ();
52- $ jwt = $ parser ->parse ($ jwt );
53- $ cnf = $ jwt ->getClaim ("cnf " );
56+ $ jwtConfig = $ configuration = Configuration:: forUnsecuredSigner ();
57+ $ jwt = $ jwtConfig -> parser () ->parse ($ jwt );
58+ $ cnf = $ jwt ->claims ()-> get ("cnf " );
5459
55- if ($ cnf-> jkt == $ dpopKey ) {
60+ if ($ cnf[ ' jkt ' ] == $ dpopKey ) {
5661 //error_log("dpopKey matches");
5762 return true ;
5863 }
@@ -88,17 +93,16 @@ private function validateDpop($dpop, $request) {
8893 received previously (see Section 9.1).
8994 */
9095 //error_log("1");
91-
92- $ parser = new \Lcobucci \JWT \Parser ();
9396 // 1. the string value is a well-formed JWT,
94- $ dpop = $ parser ->parse ($ dpop );
97+ $ jwtConfig = $ configuration = Configuration::forUnsecuredSigner ();
98+ $ dpop = $ jwtConfig ->parser ()->parse ($ dpop );
9599
96100 //error_log("2");
97101 // 2. all required claims are contained in the JWT,
98- $ htm = $ dpop ->getClaim ("htm " ); // http method
99- $ htu = $ dpop ->getClaim ("htu " ); // http uri
100- $ typ = $ dpop ->getHeader ("typ " );
101- $ alg = $ dpop ->getHeader ("alg " );
102+ $ htm = $ dpop ->claims ()-> get ("htm " ); // http method
103+ $ htu = $ dpop ->claims ()-> get ("htu " ); // http uri
104+ $ typ = $ dpop ->headers ()-> get ("typ " );
105+ $ alg = $ dpop ->headers ()-> get ("alg " );
102106
103107 //error_log("3");
104108 // 3. the "typ" field in the header has the value "dpop+jwt",
@@ -117,7 +121,7 @@ private function validateDpop($dpop, $request) {
117121 //error_log("5");
118122 // 5. that the JWT is signed using the public key contained in the
119123 // "jwk" header of the JWT,
120- $ jwk = $ dpop ->getHeader ("jwk " );
124+ $ jwk = $ dpop ->headers ()-> get ("jwk " );
121125 $ webTokenJwk = \Jose \Component \Core \JWK ::createFromJson (json_encode ($ jwk ));
122126 switch ($ alg ) {
123127 case "RS256 " :
@@ -126,16 +130,21 @@ private function validateDpop($dpop, $request) {
126130 break ;
127131 case "ES256 " :
128132 $ pem = \Jose \Component \Core \Util \ECKey::convertToPEM ($ webTokenJwk );
129- $ signer = new \Lcobucci \JWT \Signer \Ecdsa \Sha256 ();
133+ $ signer = \Lcobucci \JWT \Signer \Ecdsa \Sha256:: create ();
130134 break ;
131135 default :
132136 throw new \Exception ("unsupported algorithm " );
133137 break ;
134138 }
135- $ key = new \Lcobucci \JWT \Signer \Key ($ pem );
136- if (!$ dpop ->verify ($ signer , $ key )) {
137- throw new \Exception ("invalid signature " );
138- }
139+ $ key = InMemory::plainText ($ pem );
140+ $ jwtConfig = Configuration::forSymmetricSigner ($ signer , InMemory::plainText ($ pem ));
141+
142+ // FIXME: Add constraints;
143+ // $constraint = new LooseValidAt($clock, $leeway); // It will use the current time to validate (iat, nbf and exp)
144+ // $jwtConfig->setValidationConstraints($constraint);
145+ // if (!$jwtConfig->validator()->validate($dpop, ...$jwtConfig->validationConstraints())) {
146+ // throw new \Exception("invalid signature");
147+ // }
139148
140149 //error_log("6");
141150 // 6. the "htm" claim matches the HTTP method value of the HTTP request
@@ -162,9 +171,12 @@ private function validateDpop($dpop, $request) {
162171
163172 //error_log("8");
164173 // 8. the token was issued within an acceptable timeframe (see Section 9.1), and
165- $ leeway = 5 ; // allow 5 seconds clock skew
166- $ validationData = new ValidationData (time () + $ leeway ); // It will use the current time to validate (iat, nbf and exp)
167- if (!$ dpop ->validate ($ validationData )) {
174+
175+ $ leeway = new \DateInterval ("PT60S " ); // allow 60 seconds clock skew
176+ $ clock = SystemClock::fromUTC ();
177+ $ constraint = new LooseValidAt ($ clock , $ leeway ); // It will use the current time to validate (iat, nbf and exp)
178+ $ jwtConfig ->setValidationConstraints ($ constraint );
179+ if (!$ jwtConfig ->validator ()->validate ($ dpop , ...$ jwtConfig ->validationConstraints ())) {
168180 throw new \Exception ("token timing is invalid " );
169181 }
170182
@@ -176,14 +188,14 @@ private function validateDpop($dpop, $request) {
176188 }
177189
178190 private function getSubjectFromJwt ($ jwt ) {
179- $ parser = new \ Lcobucci \ JWT \ Parser ();
191+ $ jwtConfig = $ configuration = Configuration:: forUnsecuredSigner ();
180192 try {
181- $ jwt = $ parser ->parse ($ jwt );
193+ $ jwt = $ jwtConfig -> parser () ->parse ($ jwt );
182194 } catch (\Exception $ e ) {
183195 return $ this ->server ->getResponse ()->withStatus (409 , "Invalid JWT token " );
184196 }
185197
186- $ sub = $ jwt ->getClaim ("sub " );
198+ $ sub = $ jwt ->claims ()-> get ("sub " );
187199 return $ sub ;
188200 }
189201}
0 commit comments