KEYCLOAK-15448 FAPI-RW : Error Response on OIDC private_key_jwt Client Authentication Error (400 error=invalid_client)
This commit is contained in:
parent
df52c12ebb
commit
cbb79f0430
2 changed files with 15 additions and 13 deletions
|
@ -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 {
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Reference in a new issue