Handle OIDC authz request with "response_type" missing and "response_mode=form_post"

Closes #10144
This commit is contained in:
Takashi Norimatsu 2022-03-04 10:11:57 +09:00 committed by Marek Posolda
parent 6c64d465ea
commit 201277b897
4 changed files with 59 additions and 1 deletions

View file

@ -151,7 +151,12 @@ public class AuthorizationEndpoint extends AuthorizationEndpointBase {
this.parsedResponseType = checker.getParsedResponseType();
this.parsedResponseMode = checker.getParsedResponseMode();
} catch (AuthorizationEndpointChecker.AuthorizationCheckException ex) {
OIDCResponseMode responseMode = checker.getParsedResponseMode() != null ? checker.getParsedResponseMode() : OIDCResponseMode.QUERY;
OIDCResponseMode responseMode = null;
if (checker.isInvalidResponseType(ex)) {
responseMode = OIDCResponseMode.parseWhenInvalidResponseType(request.getResponseMode());
} else {
responseMode = checker.getParsedResponseMode() != null ? checker.getParsedResponseMode() : OIDCResponseMode.QUERY;
}
return redirectErrorToClient(responseMode, ex.getError(), ex.getErrorDescription());
}
if (action == null) {

View file

@ -193,6 +193,10 @@ public class AuthorizationEndpointChecker {
}
}
public boolean isInvalidResponseType(AuthorizationEndpointChecker.AuthorizationCheckException ex) {
return "Missing parameter: response_type".equals(ex.getErrorDescription()) || OAuthErrorException.UNSUPPORTED_RESPONSE_TYPE.equals(ex.getError());
}
public void checkInvalidRequestMessage() throws AuthorizationCheckException {
if (request.getInvalidRequestMessage() != null) {
event.error(Errors.INVALID_REQUEST);

View file

@ -46,6 +46,21 @@ public enum OIDCResponseMode {
}
}
public static OIDCResponseMode parseWhenInvalidResponseType(String responseMode) {
if (responseMode == null) {
return OIDCResponseMode.QUERY;
} else if(responseMode.equals("jwt")) {
return OIDCResponseMode.QUERY_JWT;
} else {
for (OIDCResponseMode c : OIDCResponseMode.values()) {
if (c.value.equals(responseMode)) {
return c;
}
}
return OIDCResponseMode.QUERY;
}
}
public String value() {
return value;
}

View file

@ -158,6 +158,40 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest {
events.expectLogin().error(Errors.INVALID_REQUEST).user((String) null).session((String) null).clearDetails().detail(Details.RESPONSE_TYPE, "tokenn").assertEvent();
}
@Test
public void authorizationRequestFormPostResponseModeInvalidResponseType() throws IOException {
oauth.responseMode(OIDCResponseMode.FORM_POST.value());
oauth.responseType("tokenn");
oauth.stateParamHardcoded("OpenIdConnect.AuthenticationProperties=2302984sdlk");
UriBuilder b = UriBuilder.fromUri(oauth.getLoginFormUrl());
driver.navigate().to(b.build().toURL());
String error = driver.findElement(By.id("error")).getText();
String state = driver.findElement(By.id("state")).getText();
assertEquals(OAuthErrorException.UNSUPPORTED_RESPONSE_TYPE, error);
assertEquals("OpenIdConnect.AuthenticationProperties=2302984sdlk", state);
}
@Test
public void authorizationRequestFormPostResponseModeWithoutResponseType() throws IOException {
oauth.responseMode(OIDCResponseMode.FORM_POST.value());
oauth.responseType(null);
oauth.stateParamHardcoded("OpenIdConnect.AuthenticationProperties=2302984sdlk");
UriBuilder b = UriBuilder.fromUri(oauth.getLoginFormUrl());
driver.navigate().to(b.build().toURL());
String error = driver.findElement(By.id("error")).getText();
String errorDescription = driver.findElement(By.id("error_description")).getText();
String state = driver.findElement(By.id("state")).getText();
assertEquals(OAuthErrorException.INVALID_REQUEST, error);
assertEquals("Missing parameter: response_type", errorDescription);
assertEquals("OpenIdConnect.AuthenticationProperties=2302984sdlk", state);
}
// KEYCLOAK-3281
@Test
public void authorizationRequestFormPostResponseMode() throws IOException {