Add duplicate parameter check for UserInfo endpoint. (#14024)
Closes #14016
This commit is contained in:
parent
917e8668cb
commit
1cdc21f0ff
2 changed files with 34 additions and 1 deletions
|
@ -19,6 +19,7 @@ package org.keycloak.protocol.oidc.endpoints;
|
|||
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||
import org.jboss.resteasy.spi.HttpRequest;
|
||||
import org.jboss.resteasy.spi.HttpResponse;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.OAuthErrorException;
|
||||
import org.keycloak.TokenCategory;
|
||||
import org.keycloak.TokenVerifier;
|
||||
|
@ -77,6 +78,7 @@ import javax.ws.rs.Path;
|
|||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
@ -136,7 +138,9 @@ public class UserInfoEndpoint {
|
|||
|
||||
// Fallback to form parameter
|
||||
if (accessToken == null) {
|
||||
accessToken = request.getDecodedFormParameters().getFirst("access_token");
|
||||
MultivaluedMap<String, String> formParams = request.getDecodedFormParameters();
|
||||
checkAccessTokenDuplicated(formParams);
|
||||
accessToken = formParams.getFirst(OAuth2Constants.ACCESS_TOKEN);
|
||||
}
|
||||
|
||||
return issueUserInfo(accessToken);
|
||||
|
@ -393,4 +397,13 @@ public class UserInfoEndpoint {
|
|||
throw newUnauthorizedErrorResponseException(OAuthErrorException.INVALID_TOKEN, "Stale token");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAccessTokenDuplicated(MultivaluedMap<String, String> formParams) {
|
||||
// If access_token is not provided, error is thrown in issueUserInfo().
|
||||
// Only checks duplication of access token parameter in this function.
|
||||
if (formParams.containsKey(OAuth2Constants.ACCESS_TOKEN) && formParams.get(OAuth2Constants.ACCESS_TOKEN).size() != 1) {
|
||||
cors = Cors.add(request).auth().allowedMethods(request.getHttpMethod()).auth().exposedHeaders(Cors.ACCESS_CONTROL_ALLOW_METHODS);
|
||||
throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_REQUEST, "duplicated parameter", Response.Status.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -707,6 +707,26 @@ public class UserInfoTest extends AbstractKeycloakTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnsuccessfulUserInfoRequestwithDuplicatedParams() {
|
||||
Client client = AdminClientUtil.createResteasyClient();
|
||||
|
||||
try {
|
||||
AccessTokenResponse accessTokenResponse = executeGrantAccessTokenRequest(client);
|
||||
|
||||
Form form = new Form();
|
||||
form.param("access_token", accessTokenResponse.getToken());
|
||||
form.param("access_token", accessTokenResponse.getToken());
|
||||
|
||||
WebTarget userInfoTarget = UserInfoClientUtil.getUserInfoWebTarget(client);
|
||||
Response response = userInfoTarget.request().post(Entity.form(form));
|
||||
response.close();
|
||||
assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUserInfoRequestWithSamlClient() throws Exception {
|
||||
// obtain an access token
|
||||
|
|
Loading…
Reference in a new issue