11<?php
22
3- namespace Northwestern \SysDev \SOA \Auth \OAuth2 ;
3+ namespace Northwestern \SysDev \SOA \Auth \OAuth2 \ TokenVerifier \ Contract ;
44
55use Firebase \JWT \JWK ;
66use GuzzleHttp \Client ;
1111use Lcobucci \JWT \Signer \Key \InMemory ;
1212use Lcobucci \JWT \Signer \Rsa \Sha256 ;
1313use Lcobucci \JWT \UnencryptedToken ;
14- use Lcobucci \JWT \Validation \Constraint \ IssuedBy ;
14+ use Lcobucci \JWT \Validation \Constraint ;
1515use Lcobucci \JWT \Validation \Constraint \LooseValidAt ;
1616use Lcobucci \JWT \Validation \Constraint \SignedWith ;
1717use Lcobucci \JWT \Validation \RequiredConstraintsViolated ;
1818
19- class AzureTokenVerifier
19+ abstract class AbstractAzureTokenVerifier
2020{
2121 public const KEYS_URL = 'https://login.microsoftonline.com/common/discovery/v2.0/keys ' ;
2222
23- public const ISSUER = 'https://login.microsoftonline.com/7d76d361-8277-4708-a477-64e8366cd1bc/v2.0 ' ; // UUID is our tenant ID
23+ /**
24+ * The list of additional constraints to validate the token.
25+ *
26+ * {@see SignedWith} (for valid Microsoft keys) and {@see LooseValidAt} will always be applied.
27+ *
28+ * @return Constraint[]
29+ */
30+ abstract protected function additionalTokenConstraints (): array ;
2431
2532 /**
2633 * Parses the ID token, validates it with Microsoft's signing keys, and returns it.
@@ -29,12 +36,12 @@ class AzureTokenVerifier
2936 *
3037 * @throws InvalidStateException
3138 */
32- public static function parseAndVerify (string $ jwt ): UnencryptedToken
39+ public function parseAndVerify (string $ jwt ): UnencryptedToken
3340 {
3441 $ jwtContainer = Configuration::forUnsecuredSigner ();
3542 $ token = $ jwtContainer ->parser ()->parse ($ jwt );
3643
37- $ data = self :: loadKeys ();
44+ $ data = $ this -> loadKeys ();
3845
3946 $ publicKeys = JWK ::parseKeySet ($ data );
4047 $ kid = $ token ->headers ()->get ('kid ' );
@@ -43,8 +50,8 @@ public static function parseAndVerify(string $jwt): UnencryptedToken
4350 $ publicKey = openssl_pkey_get_details ($ publicKeys [$ kid ]);
4451 $ constraints = [
4552 new SignedWith (new Sha256 (), InMemory::plainText ($ publicKey ['key ' ])),
46- new IssuedBy (self ::ISSUER ),
4753 new LooseValidAt (SystemClock::fromSystemTimezone ()),
54+ ...$ this ->additionalTokenConstraints (),
4855 ];
4956
5057 try {
@@ -64,12 +71,12 @@ public static function parseAndVerify(string $jwt): UnencryptedToken
6471 throw new InvalidStateException ('Invalid JWT Signature ' );
6572 }
6673
67- protected static function loadKeys ()
74+ private function loadKeys ()
6875 {
6976 return Cache::remember ('socialite:Azure-JWKSet ' , 5 * 60 , function () {
7077 $ response = (new Client ())->get (self ::KEYS_URL );
7178
7279 return json_decode ($ response ->getBody ()->getContents (), true );
7380 });
7481 }
75- }
82+ }
0 commit comments