44namespace Office365 \Runtime \Auth ;
55
66use Exception ;
7+ use Firebase \JWT \JWT ;
78use Office365 \Runtime \Http \HttpMethod ;
89use Office365 \Runtime \Http \RequestOptions ;
910use Office365 \Runtime \Http \Requests ;
@@ -20,6 +21,13 @@ class AADTokenProvider extends BaseTokenProvider
2021 */
2122 private static $ TokenEndpoint = '/oauth2/token ' ;
2223
24+
25+ /**
26+ * @var string
27+ */
28+ private static $ TokenEndpointV2 = '/oauth2/v2.0/token ' ;
29+
30+
2331 /**
2432 * @var string
2533 */
@@ -45,6 +53,10 @@ public function __construct($tenant)
4553 $ this ->authorityUrl = self ::$ AuthorityUrl . $ tenant ;
4654 }
4755
56+ public function getTokenUrl ($ useV2 ){
57+ return $ this ->authorityUrl . ($ useV2 ? self ::$ TokenEndpointV2 : self ::$ TokenEndpoint );
58+ }
59+
4860
4961 /**
5062 * @param string $resource
@@ -87,6 +99,36 @@ public function acquireTokenForClientCredential($resource, $clientCredentials, $
8799 }
88100
89101
102+ /**
103+ * @param CertificateCredentials $credentials
104+ * @throws Exception
105+ */
106+ public function acquireTokenForClientCertificate ($ credentials ){
107+ $ header = [
108+ 'x5t ' => base64_encode (hex2bin ($ credentials ->Thumbprint )),
109+ ];
110+ $ now = time ();
111+ $ payload = [
112+ 'aud ' => $ this ->getTokenUrl (true ),
113+ 'exp ' => $ now + 360 ,
114+ 'iat ' => $ now ,
115+ 'iss ' => $ credentials ->ClientId ,
116+ 'jti ' => bin2hex (random_bytes (20 )),
117+ 'nbf ' => $ now ,
118+ 'sub ' => $ credentials ->ClientId ,
119+ ];
120+ $ jwt = JWT ::encode ($ payload , str_replace ('\n ' , "\n" , $ credentials ->PrivateKey ), 'RS256 ' , null , $ header );
121+
122+ $ params ['client_assertion_type ' ] = 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer ' ;
123+ $ params ['client_assertion ' ] = $ jwt ;
124+ $ params ['grant_type ' ] = "client_credentials " ;
125+ $ params ['scope ' ] = implode (" " , $ credentials ->Scope );
126+
127+ return $ this ->acquireToken ($ params , true );
128+ }
129+
130+
131+
90132 /**
91133 * @param string $resource
92134 * @param string $clientId
@@ -140,24 +182,26 @@ public function acquireTokenByAuthorizationCode($resource, $clientId, $clientSec
140182 /**
141183 * Acquires the access token
142184 * @param array $parameters
185+ * @param bool $useV2
143186 * @return mixed
144187 * @throws Exception
145188 */
146- public function acquireToken ($ parameters )
189+ public function acquireToken ($ parameters, $ useV2 = false )
147190 {
148- $ request = $ this ->prepareTokenRequest ($ parameters );
191+ $ request = $ this ->prepareTokenRequest ($ parameters, $ useV2 );
149192 $ response = Requests::execute ($ request );
150193 $ response ->validate ();
151194 return $ this ->normalizeToken ($ response ->getContent ());
152195 }
153196
154197 /**
155- * @param $parameters
198+ * @param array $parameters
199+ * @param bool $useV2
156200 * @return RequestOptions
157201 */
158- private function prepareTokenRequest ($ parameters )
202+ private function prepareTokenRequest ($ parameters, $ useV2 )
159203 {
160- $ tokenUrl = $ this ->authorityUrl . self :: $ TokenEndpoint ;
204+ $ tokenUrl = $ this ->getTokenUrl ( $ useV2 ) ;
161205 $ request = new RequestOptions ($ tokenUrl );
162206 $ request ->ensureHeader ('content-Type ' , 'application/x-www-form-urlencoded ' );
163207 $ request ->Method = HttpMethod::Post;
0 commit comments