From fc514aa2567ca353b8c3dc380ff80b9af88c9295 Mon Sep 17 00:00:00 2001 From: Pedro Igor Date: Wed, 29 Jan 2020 14:06:29 -0300 Subject: [PATCH] [KEYCLOAK-12792] - Invalid nonce handling in OIDC identity brokering --- .../oidc/AbstractOAuth2IdentityProvider.java | 7 -- .../broker/oidc/OIDCIdentityProvider.java | 42 +++++++++ .../keycloak/testsuite/util/OAuthClient.java | 18 ++++ .../KcOidcBrokerNonceParameterTest.java | 88 +++++++++++++++++++ 4 files changed, 148 insertions(+), 7 deletions(-) create mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerNonceParameterTest.java diff --git a/services/src/main/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProvider.java b/services/src/main/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProvider.java index 7f31603ae1..b927d2bbdb 100755 --- a/services/src/main/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProvider.java +++ b/services/src/main/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProvider.java @@ -335,13 +335,6 @@ public abstract class AbstractOAuth2IdentityProvider 0) { long accessTokenExpiration = Time.currentTime() + tokenResponse.getExpiresIn(); @@ -453,6 +460,7 @@ public class OIDCIdentityProvider extends AbstractOAuth2IdentityProvider createConsumerClients(SuiteContext suiteContext) { + List clients = new ArrayList<>(super.createConsumerClients(suiteContext)); + + clients.add(ClientBuilder.create().clientId("consumer-client") + .publicClient() + .redirectUris("http://localhost:8180/auth/realms/master/app/auth/*", "https://localhost:8543/auth/realms/master/app/auth/*") + .publicClient().build()); + + return clients; + } + }; + } + + @Override + protected void loginUser() { + updateExecutions(AbstractBrokerTest::disableUpdateProfileOnFirstLogin); + + oauth.realm(bc.consumerRealmName()); + oauth.clientId("consumer-client"); + oauth.nonce("123456"); + + OAuthClient.AuthorizationEndpointResponse authzResponse = oauth + .doLoginSocial(bc.getIDPAlias(), bc.getUserLogin(), bc.getUserPassword()); + String code = authzResponse.getCode(); + OAuthClient.AccessTokenResponse response = oauth.doAccessTokenRequest(code, null); + IDToken idToken = toIdToken(response.getIdToken()); + + Assert.assertEquals("123456", idToken.getNonce()); + } + + @Test + public void testNonceNotSet() { + updateExecutions(AbstractBrokerTest::disableUpdateProfileOnFirstLogin); + + oauth.realm(bc.consumerRealmName()); + oauth.clientId("consumer-client"); + oauth.nonce(null); + + OAuthClient.AuthorizationEndpointResponse authzResponse = oauth + .doLoginSocial(bc.getIDPAlias(), bc.getUserLogin(), bc.getUserPassword()); + String code = authzResponse.getCode(); + OAuthClient.AccessTokenResponse response = oauth.doAccessTokenRequest(code, null); + IDToken idToken = toIdToken(response.getIdToken()); + + Assert.assertNull(idToken.getNonce()); + } + + protected IDToken toIdToken(String encoded) { + IDToken idToken; + + try { + idToken = new JWSInput(encoded).readJsonContent(IDToken.class); + } catch (JWSInputException cause) { + throw new RuntimeException("Failed to deserialize RPT", cause); + } + return idToken; + } +}