@@ -1557,6 +1557,61 @@ public function testAuthenticateImplicitFlowEncrypted()
15571557 $ this ->assertEquals ($ idToken , $ client ->getIdToken ());
15581558 }
15591559
1560+ public function testAuthenticateImplicitFlowRejectedWithInvalidState ()
1561+ {
1562+ // Mock the OpenIDConnectClient, only mocking the fetchURL method
1563+ $ client = new OpenIDConnectClient (
1564+ 'https://example.org ' ,
1565+ 'fake-client-id ' ,
1566+ 'fake-client-secret ' ,
1567+ );
1568+
1569+ // Allow implicit flow
1570+ $ client ->setAllowImplicitFlow (true );
1571+
1572+ $ state = bin2hex (random_bytes (6 ));
1573+ $ nonce = bin2hex (random_bytes (6 ));
1574+
1575+ // Simulate the state and nonce have been set in the session
1576+ $ _SESSION ['openid_connect_state ' ] = $ state ;
1577+ $ _SESSION ['openid_connect_nonce ' ] = $ nonce ;
1578+
1579+ // Simulate incoming request with ID token and wrong state
1580+ $ _REQUEST ['id_token ' ] = bin2hex (random_bytes (6 ));
1581+ $ _REQUEST ['state ' ] = "other state " ;
1582+
1583+ // Call the authenticate method, should throw an exception
1584+ $ this ->expectException (OpenIDConnectClientException::class);
1585+ $ client ->authenticate ();
1586+ }
1587+
1588+ public function testAuthenticateImplicitFlowRejectedWithNoState ()
1589+ {
1590+ // Mock the OpenIDConnectClient, only mocking the fetchURL method
1591+ $ client = new OpenIDConnectClient (
1592+ 'https://example.org ' ,
1593+ 'fake-client-id ' ,
1594+ 'fake-client-secret ' ,
1595+ );
1596+
1597+ // Allow implicit flow
1598+ $ client ->setAllowImplicitFlow (true );
1599+
1600+ $ state = bin2hex (random_bytes (6 ));
1601+ $ nonce = bin2hex (random_bytes (6 ));
1602+
1603+ // Simulate the state and nonce have been set in the session
1604+ $ _SESSION ['openid_connect_state ' ] = $ state ;
1605+ $ _SESSION ['openid_connect_nonce ' ] = $ nonce ;
1606+
1607+ // Simulate incoming request with ID token and without state
1608+ $ _REQUEST ['id_token ' ] = bin2hex (random_bytes (6 ));
1609+
1610+ // Call the authenticate method, should throw an exception
1611+ $ this ->expectException (OpenIDConnectClientException::class);
1612+ $ client ->authenticate ();
1613+ }
1614+
15601615 public function testAuthenticateAuthorizationCodeFlow ()
15611616 {
15621617 // Create a new RSA key pair for signing the ID token
@@ -1831,6 +1886,55 @@ public function testAuthenticateAuthorizationCodeFlowEncrypted()
18311886 $ this ->assertEquals ($ idToken , $ client ->getIdToken ());
18321887 }
18331888
1889+ public function testAuthenticateImplicitAuthorizationCodeFlowWithInvalidState ()
1890+ {
1891+ // Mock the OpenIDConnectClient, only mocking the fetchURL method
1892+ $ client = new OpenIDConnectClient (
1893+ 'https://example.org ' ,
1894+ 'fake-client-id ' ,
1895+ 'fake-client-secret ' ,
1896+ );
1897+
1898+ $ state = bin2hex (random_bytes (6 ));
1899+ $ nonce = bin2hex (random_bytes (6 ));
1900+
1901+ // Simulate the state and nonce have been set in the session
1902+ $ _SESSION ['openid_connect_state ' ] = $ state ;
1903+ $ _SESSION ['openid_connect_nonce ' ] = $ nonce ;
1904+
1905+ // Simulate incoming request with code and wrong state
1906+ $ _REQUEST ['code ' ] = bin2hex (random_bytes (6 ));
1907+ $ _REQUEST ['state ' ] = "other state " ;
1908+
1909+ // Call the authenticate method, should throw an exception
1910+ $ this ->expectException (OpenIDConnectClientException::class);
1911+ $ client ->authenticate ();
1912+ }
1913+
1914+ public function testAuthenticateAuthorizationCodeFlowWithNoState ()
1915+ {
1916+ // Mock the OpenIDConnectClient, only mocking the fetchURL method
1917+ $ client = new OpenIDConnectClient (
1918+ 'https://example.org ' ,
1919+ 'fake-client-id ' ,
1920+ 'fake-client-secret ' ,
1921+ );
1922+
1923+ $ state = bin2hex (random_bytes (6 ));
1924+ $ nonce = bin2hex (random_bytes (6 ));
1925+
1926+ // Simulate the state and nonce have been set in the session
1927+ $ _SESSION ['openid_connect_state ' ] = $ state ;
1928+ $ _SESSION ['openid_connect_nonce ' ] = $ nonce ;
1929+
1930+ // Simulate incoming request with code and without state
1931+ $ _REQUEST ['code ' ] = bin2hex (random_bytes (6 ));
1932+
1933+ // Call the authenticate method, should throw an exception
1934+ $ this ->expectException (OpenIDConnectClientException::class);
1935+ $ client ->authenticate ();
1936+ }
1937+
18341938 public function testRequestUserInfoUnsignedUnencrypted ()
18351939 {
18361940 // Create a new RSA key pair for signing the ID token
0 commit comments