Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public interface Errors {
String CLIENT_DISABLED = "client_disabled";
String INVALID_CLIENT_CREDENTIALS = "invalid_client_credentials";
String INVALID_CLIENT = "invalid_client";
String UNAUTHORIZED_CLIENT ="unauthorized_client";
String CONSENT_DENIED = "consent_denied";
String RESOLVE_REQUIRED_ACTIONS = "resolve_required_actions";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,8 +364,7 @@ private ClientModel authenticateClient() {

if (client == null) {
event.error(Errors.INVALID_REQUEST);
throw new ErrorPageException(session, null, Response.Status.BAD_REQUEST, Messages.MISSING_PARAMETER,
OIDCLoginProtocol.CLIENT_ID_PARAM);
throw new ErrorResponseException(Errors.INVALID_REQUEST, "Missing parameters:"+ OIDCLoginProtocol.CLIENT_ID_PARAM,Response.Status.BAD_REQUEST);
}

checkClient(client.getClientId());
Expand All @@ -376,33 +375,30 @@ private ClientModel authenticateClient() {
private ClientModel checkClient(String clientId) {
if (clientId == null) {
event.error(Errors.INVALID_REQUEST);
throw new ErrorPageException(session, null, Response.Status.BAD_REQUEST,
Messages.MISSING_PARAMETER, OIDCLoginProtocol.CLIENT_ID_PARAM);
throw new ErrorResponseException(Errors.INVALID_REQUEST, "Missing parameters:"+ OIDCLoginProtocol.CLIENT_ID_PARAM, Response.Status.BAD_REQUEST);
}

event.client(clientId);

ClientModel client = realm.getClientByClientId(clientId);
if (client == null) {
event.error(Errors.CLIENT_NOT_FOUND);
throw new ErrorPageException(session, null, Response.Status.BAD_REQUEST,
Messages.CLIENT_NOT_FOUND);
throw new ErrorResponseException(Errors.INVALID_CLIENT, "Client not found.", Response.Status.BAD_REQUEST);
}

if (!client.isEnabled()) {
event.error(Errors.CLIENT_DISABLED);
throw new ErrorPageException(session, null, Response.Status.BAD_REQUEST, Messages.CLIENT_DISABLED);
throw new ErrorResponseException(Errors.INVALID_CLIENT, "Client disabled.", Response.Status.BAD_REQUEST);
}

if (!realm.getOAuth2DeviceConfig().isOAuth2DeviceAuthorizationGrantEnabled(client)) {
event.error(Errors.NOT_ALLOWED);
throw new ErrorPageException(session, null, Response.Status.BAD_REQUEST,
Messages.OAUTH2_DEVICE_AUTHORIZATION_GRANT_DISABLED);
throw new ErrorResponseException(Errors.UNAUTHORIZED_CLIENT, "Client is not allowed to initiate OAuth 2.0 Device Authorization Grant. The flow is disabled for the client.", Response.Status.BAD_REQUEST);
}

if (client.isBearerOnly()) {
event.error(Errors.NOT_ALLOWED);
throw new ErrorPageException(session, null, Response.Status.FORBIDDEN, Messages.BEARER_ONLY);
throw new ErrorResponseException(Errors.UNAUTHORIZED_CLIENT, "Bearer-only applications are not allowed to initiate browser login.", Response.Status.FORBIDDEN);
}

String protocol = client.getProtocol();
Expand All @@ -413,7 +409,7 @@ private ClientModel checkClient(String clientId) {
}
if (!protocol.equals(OIDCLoginProtocol.LOGIN_PROTOCOL)) {
event.error(Errors.INVALID_CLIENT);
throw new ErrorPageException(session, null, Response.Status.BAD_REQUEST, "Wrong client protocol.");
throw new ErrorResponseException(Errors.UNAUTHORIZED_CLIENT, "Wrong client protocol." , Response.Status.BAD_REQUEST);
}

session.getContext().setClient(client);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.keycloak.OAuth2Constants;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.events.Errors;
import org.keycloak.models.ClientScopeModel;
import org.keycloak.models.OAuth2DeviceConfig;
import org.keycloak.models.utils.KeycloakModelUtils;
Expand Down Expand Up @@ -851,6 +852,51 @@ public void testConsentCancelCannotBeReused() throws Exception {
verificationPage.assertInvalidUserCodePage();
}

@Test
public void testNotFoundClient() throws Exception {
oauth.realm(REALM_NAME);
oauth.clientId("test-device-public2");
OAuthClient.DeviceAuthorizationResponse response = oauth.doDeviceAuthorizationRequest("test-device-public2", null);

Assert.assertEquals(400, response.getStatusCode());
Assert.assertEquals(Errors.INVALID_CLIENT, response.getError());
Assert.assertEquals("Invalid client credentials", response.getErrorDescription());
}
@Test
public void testClientWithErrors() throws Exception {
try {
ClientResource client = ApiUtil.findClientByClientId(adminClient.realm(REALM_NAME), DEVICE_APP_PUBLIC);
ClientRepresentation clientRepresentation = client.toRepresentation();
clientRepresentation.getAttributes().put(OAuth2DeviceConfig.OAUTH2_DEVICE_AUTHORIZATION_GRANT_ENABLED, "false");
client.update(clientRepresentation);
oauth.realm(REALM_NAME);
oauth.clientId(DEVICE_APP_PUBLIC);

//DeviceAuthorizationGrant not enabled
OAuthClient.DeviceAuthorizationResponse response = oauth.doDeviceAuthorizationRequest(DEVICE_APP_PUBLIC, null);
Assert.assertEquals(400, response.getStatusCode());
Assert.assertEquals(Errors.UNAUTHORIZED_CLIENT, response.getError());
Assert.assertEquals("Client is not allowed to initiate OAuth 2.0 Device Authorization Grant. The flow is disabled for the client.", response.getErrorDescription());

clientRepresentation.getAttributes().put(OAuth2DeviceConfig.OAUTH2_DEVICE_AUTHORIZATION_GRANT_ENABLED, "true");
clientRepresentation.setBearerOnly(true);
client.update(clientRepresentation);

//BearerOnly client
response = oauth.doDeviceAuthorizationRequest(DEVICE_APP_PUBLIC, null);
Assert.assertEquals(403, response.getStatusCode());
Assert.assertEquals(Errors.UNAUTHORIZED_CLIENT, response.getError());
Assert.assertEquals("Bearer-only applications are not allowed to initiate browser login.", response.getErrorDescription());

} finally {
ClientResource client = ApiUtil.findClientByClientId(adminClient.realm(REALM_NAME), DEVICE_APP_PUBLIC);
ClientRepresentation clientRepresentation = client.toRepresentation();
clientRepresentation.getAttributes().put(OAuth2DeviceConfig.OAUTH2_DEVICE_AUTHORIZATION_GRANT_ENABLED, "true");
clientRepresentation.setBearerOnly(false);
client.update(clientRepresentation);
}
}

private void openVerificationPage(String verificationUri) {
driver.navigate().to(verificationUri);
}
Expand Down