@@ -824,6 +824,49 @@ protected function requestTokens($code, $headers = array()) {
824824 return $ this ->tokenResponse ;
825825 }
826826
827+ /**
828+ * Request RFC8693 Token Exchange
829+ * https://datatracker.ietf.org/doc/html/rfc8693
830+ *
831+ * @param string $subjectToken
832+ * @param string $subjectTokenType
833+ * @param string $audience
834+ * @return mixed
835+ * @throws OpenIDConnectClientException
836+ */
837+ public function requestTokenExchange ($ subjectToken , $ subjectTokenType , $ audience = '' ) {
838+ $ token_endpoint = $ this ->getProviderConfigValue ('token_endpoint ' );
839+ $ token_endpoint_auth_methods_supported = $ this ->getProviderConfigValue ('token_endpoint_auth_methods_supported ' , ['client_secret_basic ' ]);
840+ $ headers = [];
841+ $ grant_type = 'urn:ietf:params:oauth:grant-type:token-exchange ' ;
842+
843+ $ post_data = array (
844+ 'grant_type ' => $ grant_type ,
845+ 'subject_token_type ' => $ subjectTokenType ,
846+ 'subject_token ' => $ subjectToken ,
847+ 'client_id ' => $ this ->clientID ,
848+ 'client_secret ' => $ this ->clientSecret ,
849+ 'scope ' => implode (' ' , $ this ->scopes )
850+ );
851+
852+ if (!empty ($ audience )) {
853+ $ post_data ['audience ' ] = $ audience ;
854+ }
855+
856+ # Consider Basic authentication if provider config is set this way
857+ if (in_array ('client_secret_basic ' , $ token_endpoint_auth_methods_supported , true )) {
858+ $ headers = ['Authorization: Basic ' . base64_encode (urlencode ($ this ->clientID ) . ': ' . urlencode ($ this ->clientSecret ))];
859+ unset($ post_data ['client_secret ' ]);
860+ unset($ post_data ['client_id ' ]);
861+ }
862+
863+ // Convert token params to string format
864+ $ post_params = http_build_query ($ post_data , null , '& ' , $ this ->enc_type );
865+
866+ return json_decode ($ this ->fetchURL ($ token_endpoint , $ post_params , $ headers ));
867+ }
868+
869+
827870 /**
828871 * Requests Access token with refresh token
829872 *
0 commit comments