Allow application/jwt media type for userinfo endpoint

Closes: https://github.com/keycloak/keycloak/issues/19346
This commit is contained in:
rmartinc 2023-03-28 10:25:39 +02:00 committed by Pedro Igor
parent 2e16be623e
commit 2bb9de1a8c
3 changed files with 35 additions and 13 deletions

View file

@ -121,7 +121,7 @@ public class UserInfoEndpoint {
@Path("/")
@GET
@NoCache
@Produces(javax.ws.rs.core.MediaType.APPLICATION_JSON)
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_JWT})
public Response issueUserInfoGet() {
setupCors();
String accessToken = this.appAuthManager.extractAuthorizationHeaderTokenOrReturnNull(session.getContext().getRequestHeaders());
@ -132,7 +132,7 @@ public class UserInfoEndpoint {
@Path("/")
@POST
@NoCache
@Produces(javax.ws.rs.core.MediaType.APPLICATION_JSON)
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_JWT})
public Response issueUserInfoPost() {
setupCors();

View file

@ -23,6 +23,7 @@ import org.keycloak.representations.UserInfo;
import org.keycloak.utils.MediaType;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
@ -35,11 +36,18 @@ import java.net.URI;
public class UserInfoClientUtil {
public static Response executeUserInfoRequest_getMethod(Client client, String accessToken) {
return executeUserInfoRequest_getMethod(client, accessToken, null);
}
public static Response executeUserInfoRequest_getMethod(Client client, String accessToken, String acceptHeader) {
WebTarget userInfoTarget = getUserInfoWebTarget(client);
return userInfoTarget.request()
.header(HttpHeaders.AUTHORIZATION, "bearer " + accessToken)
.get();
Invocation.Builder builder = userInfoTarget.request()
.header(HttpHeaders.AUTHORIZATION, "bearer " + accessToken);
if (acceptHeader != null) {
builder.header(HttpHeaders.ACCEPT, acceptHeader);
}
return builder.get();
}
public static WebTarget getUserInfoWebTarget(Client client) {

View file

@ -75,6 +75,7 @@ import org.keycloak.testsuite.util.AdminClientUtil;
import org.keycloak.testsuite.util.ClientManager;
import org.keycloak.testsuite.util.OAuthClient;
import org.keycloak.testsuite.util.RealmBuilder;
import org.keycloak.testsuite.util.RoleBuilder;
import org.keycloak.testsuite.util.TokenSignatureUtil;
import org.keycloak.testsuite.util.UserInfoClientUtil;
import org.keycloak.testsuite.util.WaitUtils;
@ -107,7 +108,6 @@ import static org.junit.Assert.assertThat;
import static org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper.INCLUDE_IN_USERINFO;
import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson;
import static org.keycloak.testsuite.util.OAuthClient.AUTH_SERVER_ROOT;
import org.keycloak.testsuite.util.RoleBuilder;
/**
* @author pedroigor
@ -143,13 +143,12 @@ public class UserInfoTest extends AbstractKeycloakTest {
samlApp.setDirectAccessGrantsEnabled(true);
}
@Test
public void testSuccess_getMethod_header() throws Exception {
public void testSuccessGet(String acceptHeader) throws Exception {
Client client = AdminClientUtil.createResteasyClient();
try {
AccessTokenResponse accessTokenResponse = executeGrantAccessTokenRequest(client);
Response response = UserInfoClientUtil.executeUserInfoRequest_getMethod(client, accessTokenResponse.getToken());
Response response = UserInfoClientUtil.executeUserInfoRequest_getMethod(client, accessTokenResponse.getToken(), acceptHeader);
UserInfo userInfo = testSuccessfulUserInfoResponse(response);
testRolesAreNotInUserInfoResponse(userInfo);
@ -159,6 +158,16 @@ public class UserInfoTest extends AbstractKeycloakTest {
}
}
@Test
public void testSuccess_getMethod_header() throws Exception {
testSuccessGet(null);
}
@Test
public void testSuccess_getMethod_header_accept_json() throws Exception {
testSuccessGet(MediaType.APPLICATION_JSON);
}
@Test
public void testSuccess_postMethod_header() throws Exception {
Client client = AdminClientUtil.createResteasyClient();
@ -473,12 +482,17 @@ public class UserInfoTest extends AbstractKeycloakTest {
@Test
public void testSuccessSignedResponseES256() throws Exception {
testSuccessSignedResponse(Algorithm.ES256);
testSuccessSignedResponse(Algorithm.ES256, null);
}
@Test
public void testSuccessSignedResponsePS256() throws Exception {
testSuccessSignedResponse(Algorithm.PS256);
testSuccessSignedResponse(Algorithm.PS256, null);
}
@Test
public void testSuccessSignedResponseRS256AcceptJWT() throws Exception {
testSuccessSignedResponse(Algorithm.RS256, MediaType.APPLICATION_JWT);
}
@Test
@ -920,7 +934,7 @@ public class UserInfoTest extends AbstractKeycloakTest {
return UserInfoClientUtil.testSuccessfulUserInfoResponse(response, "test-user@localhost", "test-user@localhost");
}
private void testSuccessSignedResponse(String sigAlg) throws Exception {
private void testSuccessSignedResponse(String sigAlg, String acceptHeader) throws Exception {
try {
// Require signed userInfo request
@ -935,7 +949,7 @@ public class UserInfoTest extends AbstractKeycloakTest {
try {
AccessTokenResponse accessTokenResponse = executeGrantAccessTokenRequest(client);
Response response = UserInfoClientUtil.executeUserInfoRequest_getMethod(client, accessTokenResponse.getToken());
Response response = UserInfoClientUtil.executeUserInfoRequest_getMethod(client, accessTokenResponse.getToken(), acceptHeader);
events.expect(EventType.USER_INFO_REQUEST)
.session(Matchers.notNullValue(String.class))