diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientAuthenticator.java index 770dcaf520..04ccddf481 100644 --- a/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientAuthenticator.java +++ b/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientAuthenticator.java @@ -33,6 +33,7 @@ import javax.ws.rs.core.Response; import org.jboss.logging.Logger; import org.keycloak.OAuth2Constants; +import org.keycloak.OAuthErrorException; import org.keycloak.authentication.AuthenticationFlowError; import org.keycloak.authentication.ClientAuthenticationFlowContext; import org.keycloak.common.util.Time; @@ -185,7 +186,7 @@ public class JWTClientAuthenticator extends AbstractClientAuthenticator { context.success(); } catch (Exception e) { ServicesLogger.LOGGER.errorValidatingAssertion(e); - Response challengeResponse = ClientAuthUtil.errorResponse(Response.Status.BAD_REQUEST.getStatusCode(), "unauthorized_client", "Client authentication with signed JWT failed: " + e.getMessage()); + Response challengeResponse = ClientAuthUtil.errorResponse(Response.Status.BAD_REQUEST.getStatusCode(), OAuthErrorException.INVALID_CLIENT, "Client authentication with signed JWT failed: " + e.getMessage()); context.failure(AuthenticationFlowError.INVALID_CLIENT_CREDENTIALS, challengeResponse); } } @@ -193,7 +194,7 @@ public class JWTClientAuthenticator extends AbstractClientAuthenticator { protected PublicKey getSignatureValidationKey(ClientModel client, ClientAuthenticationFlowContext context, JWSInput jws) { PublicKey publicKey = PublicKeyStorageManager.getClientPublicKey(context.getSession(), client, jws); if (publicKey == null) { - Response challengeResponse = ClientAuthUtil.errorResponse(Response.Status.BAD_REQUEST.getStatusCode(), "unauthorized_client", "Unable to load public key"); + Response challengeResponse = ClientAuthUtil.errorResponse(Response.Status.BAD_REQUEST.getStatusCode(), OAuthErrorException.INVALID_CLIENT, "Unable to load public key"); context.failure(AuthenticationFlowError.CLIENT_CREDENTIALS_SETUP_REQUIRED, challengeResponse); return null; } else { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ClientAuthSignedJWTTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ClientAuthSignedJWTTest.java index 302b105f84..f44c89bfb6 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ClientAuthSignedJWTTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ClientAuthSignedJWTTest.java @@ -36,6 +36,7 @@ import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.keycloak.OAuth2Constants; +import org.keycloak.OAuthErrorException; import org.keycloak.adapters.AdapterUtils; import org.keycloak.adapters.authentication.JWTClientCredentialsProvider; import org.keycloak.admin.client.resource.ClientAttributeCertificateResource; @@ -744,7 +745,7 @@ public class ClientAuthSignedJWTTest extends AbstractKeycloakTest { CloseableHttpResponse resp = sendRequest(oauth.getServiceAccountUrl(), parameters); OAuthClient.AccessTokenResponse response = new OAuthClient.AccessTokenResponse(resp); - assertError(response, "client1", "unauthorized_client", "client_credentials_setup_required"); + assertError(response, "client1", OAuthErrorException.INVALID_CLIENT, "client_credentials_setup_required"); ClientManager.realm(adminClient.realm("test")).clientId("client1").updateAttribute(JWTClientAuthenticator.CERTIFICATE_ATTR, backupClient1Cert.certificate); } @@ -762,7 +763,7 @@ public class ClientAuthSignedJWTTest extends AbstractKeycloakTest { CloseableHttpResponse resp = sendRequest(oauth.getServiceAccountUrl(), parameters); OAuthClient.AccessTokenResponse response = new OAuthClient.AccessTokenResponse(resp); - assertError(response, "client1", "unauthorized_client", AuthenticationFlowError.CLIENT_CREDENTIALS_SETUP_REQUIRED.toString().toLowerCase()); + assertError(response, "client1", OAuthErrorException.INVALID_CLIENT, AuthenticationFlowError.CLIENT_CREDENTIALS_SETUP_REQUIRED.toString().toLowerCase()); } @@ -782,7 +783,7 @@ public class ClientAuthSignedJWTTest extends AbstractKeycloakTest { setTimeOffset(0); - assertError(response, "client1", "unauthorized_client", Errors.INVALID_CLIENT_CREDENTIALS); + assertError(response, "client1", OAuthErrorException.INVALID_CLIENT, Errors.INVALID_CLIENT_CREDENTIALS); } @Test @@ -801,7 +802,7 @@ public class ClientAuthSignedJWTTest extends AbstractKeycloakTest { setTimeOffset(0); - assertError(response, "client1", "unauthorized_client", Errors.INVALID_CLIENT_CREDENTIALS); + assertError(response, "client1", OAuthErrorException.INVALID_CLIENT, Errors.INVALID_CLIENT_CREDENTIALS); } @@ -820,14 +821,14 @@ public class ClientAuthSignedJWTTest extends AbstractKeycloakTest { response = doClientCredentialsGrantRequest(clientJwt); assertEquals(400, response.getStatusCode()); - assertEquals("unauthorized_client", response.getError()); + assertEquals(OAuthErrorException.INVALID_CLIENT, response.getError()); } @Test public void testMissingIdClaim() throws Exception { OAuthClient.AccessTokenResponse response = testMissingClaim("id"); - assertError(response, app1.getClientId(), "unauthorized_client", Errors.INVALID_CLIENT_CREDENTIALS); + assertError(response, app1.getClientId(), OAuthErrorException.INVALID_CLIENT, Errors.INVALID_CLIENT_CREDENTIALS); } @Test @@ -845,7 +846,7 @@ public class ClientAuthSignedJWTTest extends AbstractKeycloakTest { @Test public void testMissingAudienceClaim() throws Exception { OAuthClient.AccessTokenResponse response = testMissingClaim("audience"); - assertError(response, app1.getClientId(), "unauthorized_client", Errors.INVALID_CLIENT_CREDENTIALS); + assertError(response, app1.getClientId(), OAuthErrorException.INVALID_CLIENT, Errors.INVALID_CLIENT_CREDENTIALS); } @Test @@ -863,11 +864,11 @@ public class ClientAuthSignedJWTTest extends AbstractKeycloakTest { // Test expired lifespan response = testMissingClaim(-11, "expiration"); - assertError(response, app1.getClientId(), "unauthorized_client", Errors.INVALID_CLIENT_CREDENTIALS); + assertError(response, app1.getClientId(), OAuthErrorException.INVALID_CLIENT, Errors.INVALID_CLIENT_CREDENTIALS); // Missing exp and issuedAt should return error response = testMissingClaim("expiration", "issuedAt"); - assertError(response, app1.getClientId(), "unauthorized_client", Errors.INVALID_CLIENT_CREDENTIALS); + assertError(response, app1.getClientId(), OAuthErrorException.INVALID_CLIENT, Errors.INVALID_CLIENT_CREDENTIALS); } @Test @@ -934,7 +935,7 @@ public class ClientAuthSignedJWTTest extends AbstractKeycloakTest { @Test public void testCodeToTokenRequestFailureRS256() throws Exception { - testCodeToTokenRequestFailure(Algorithm.RS256, "unauthorized_client", "client_credentials_setup_required"); + testCodeToTokenRequestFailure(Algorithm.RS256, OAuthErrorException.INVALID_CLIENT, "client_credentials_setup_required"); } @Test @@ -1012,7 +1013,7 @@ public class ClientAuthSignedJWTTest extends AbstractKeycloakTest { OAuthClient.AccessTokenResponse response = doGrantAccessTokenRequest("test-user@localhost", "password", getClient2SignedJWT()); assertEquals(400, response.getStatusCode()); - assertEquals("unauthorized_client", response.getError()); + assertEquals(OAuthErrorException.INVALID_CLIENT, response.getError()); events.expect(EventType.LOGIN_ERROR) .client("client2")