@@ -318,6 +318,100 @@ public function testIdTokenSignedWithIncorrectClientSecret(): void
318318 });
319319 }
320320
321+ public function testIdTokenAndUserinfoSignedWithClientSecret (): void
322+ {
323+ $ idToken = generateJwt ([
324+ "iss " => "https://provider.rdobeheer.nl " ,
325+ "aud " => 'test-client-id ' ,
326+ "sub " => 'test-subject ' ,
327+ ], 'the-secret-client-secret ' );
328+
329+ $ signedUserInfo = generateJwt ([
330+ "iss " => "https://provider.rdobeheer.nl " ,
331+ "aud " => 'test-client-id ' ,
332+ "sub " => 'test-subject ' ,
333+ "email " => 'tester@rdobeheer.nl ' ,
334+ ], 'the-secret-client-secret ' );
335+
336+ Http::fake ([
337+ // Token requested by OpenIDConnectClient::authenticate() function.
338+ 'https://provider.rdobeheer.nl/token ' => Http::response ([
339+ 'access_token ' => 'access-token-from-token-endpoint ' ,
340+ 'id_token ' => $ idToken ,
341+ 'token_type ' => 'Bearer ' ,
342+ 'expires_in ' => 3600 ,
343+ ]),
344+ // User info requested by OpenIDConnectClient::requestUserInfo() function.
345+ 'https://provider.rdobeheer.nl/userinfo?schema=openid ' => Http::response (
346+ body: $ signedUserInfo ,
347+ status: 200 ,
348+ headers: [
349+ 'Content-Type ' => 'application/jwt ' ,
350+ ]
351+ ),
352+ ]);
353+
354+ // Set OIDC config
355+ $ this ->mockOpenIDConfigurationLoader ();
356+
357+ Config::set ('oidc.issuer ' , 'https://provider.rdobeheer.nl ' );
358+ Config::set ('oidc.client_id ' , 'test-client-id ' );
359+ Config::set ('oidc.client_secret ' , 'the-secret-client-secret ' );
360+
361+ // Set the current state, which is usually generated and saved in the session before login,
362+ // and sent to the issuer during the login redirect.
363+ Session::put ('openid_connect_state ' , 'some-state ' );
364+
365+ // We simulate here that the user now comes back after successful login at issuer.
366+ $ response = $ this ->getRoute ('oidc.login ' , ['code ' => 'some-code ' , 'state ' => 'some-state ' ]);
367+ $ response ->assertStatus (200 );
368+ $ response ->assertJson ([
369+ 'userInfo ' => [
370+ 'email ' => 'tester@rdobeheer.nl ' ,
371+ ]
372+ ]);
373+
374+ $ this ->assertEmpty (session ('openid_connect_state ' ));
375+ $ this ->assertEmpty (session ('openid_connect_nonce ' ));
376+
377+ Http::assertSentCount (2 );
378+ Http::assertSentInOrder ([
379+ 'https://provider.rdobeheer.nl/token ' ,
380+ 'https://provider.rdobeheer.nl/userinfo?schema=openid ' ,
381+ ]);
382+ Http::assertSent (function (Request $ request ) {
383+ if ($ request ->url () === 'https://provider.rdobeheer.nl/token ' ) {
384+ $ this ->assertSame (
385+ expected: 'POST ' ,
386+ actual: $ request ->method (),
387+ );
388+ $ this ->assertSame (
389+ expected: 'grant_type=authorization_code '
390+ . '&code=some-code '
391+ . '&redirect_uri=http%3A%2F%2Flocalhost%2Foidc%2Flogin '
392+ . '&client_id=test-client-id '
393+ . '&client_secret=the-secret-client-secret ' ,
394+ actual: $ request ->body (),
395+ );
396+ return true ;
397+ }
398+
399+ if ($ request ->url () === 'https://provider.rdobeheer.nl/userinfo?schema=openid ' ) {
400+ $ this ->assertSame (
401+ expected: 'GET ' ,
402+ actual: $ request ->method (),
403+ );
404+ $ this ->assertSame (
405+ expected: [
406+ 'Bearer access-token-from-token-endpoint '
407+ ],
408+ actual: $ request ->header ('Authorization ' ),
409+ );
410+ }
411+
412+ return true ;
413+ });
414+ }
321415
322416 public function testTokenSignedWithPrivateKey (): void
323417 {
0 commit comments