66use Laravel \Socialite \Two \AbstractProvider ;
77use Laravel \Socialite \Two \ProviderInterface ;
88use Laravel \Socialite \Two \User ;
9+ use Firebase \JWT \JWT ;
10+ use Firebase \JWT \Key ;
911use Log ;
1012
1113/**
@@ -40,6 +42,7 @@ class GenericSocialiteProvider extends AbstractProvider implements ProviderInter
4042 * {@inheritdoc}
4143 */
4244 protected $ scopeSeparator = ' ' ;
45+ protected $ idToken ;
4346
4447 /**
4548 * Return provider Url.
@@ -96,6 +99,19 @@ protected function getTokenUrl()
9699 return $ this ->getOIDCUrl () . '/token ' ;
97100 }
98101
102+ /**
103+ * Get the access token response for the given code.
104+ *
105+ * @param string $code
106+ * @return mixed
107+ */
108+ public function getAccessTokenResponse ($ code )
109+ {
110+ $ response = parent ::getAccessTokenResponse ($ code );
111+ $ this ->idToken = $ response ['id_token ' ] ?? null ;
112+ return $ response ;
113+ }
114+
99115 /**
100116 * @param string $token
101117 *
@@ -105,6 +121,15 @@ protected function getTokenUrl()
105121 */
106122 protected function getUserByToken ($ token )
107123 {
124+ $ useIdToken = config ('services.oidc.use_id_token ' , false );
125+
126+ if ($ useIdToken ) {
127+ if (!$ this ->idToken ) {
128+ throw new \Exception ('OIDC_USE_ID_TOKEN=true but id_token not received ' );
129+ }
130+ return $ this ->decodeIdToken ($ this ->idToken );
131+ }
132+
108133 $ base_url = $ this ->getOIDCUrl () . '/userinfo ' ;
109134 // If userinfo endpoint set, use it instead
110135 if (config ('services.oidc.userinfo_endpoint ' )) {
@@ -140,4 +165,22 @@ protected function mapUserToObject(array $user)
140165 }
141166 return (new User ())->setRaw ($ user )->map ($ socialite_user );
142167 }
168+
169+ protected function decodeIdToken ($ idToken )
170+ {
171+ $ alg = config ('services.oidc.jwt_alg ' , 'RS256 ' );
172+ $ key = config ('services.oidc.jwt_secret_or_key ' );
173+
174+ if (!$ key ) {
175+ throw new \Exception ('JWT secret or public key not configured ' );
176+ }
177+
178+ try {
179+ $ decoded = JWT ::decode ($ idToken , new Key ($ key , $ alg ));
180+ } catch (\Exception $ e ) {
181+ throw new \Exception ('Failed to decode ID token: ' .$ e ->getMessage (), 0 , $ e );
182+ }
183+
184+ return json_decode (json_encode ($ decoded ), true );
185+ }
143186}
0 commit comments