KEYCLOAK-3217 UserInfo endpoint wasn't accessible by POST request secured with Bearer header
This commit is contained in:
parent
2591dd862b
commit
7aafbcd5d9
2 changed files with 122 additions and 37 deletions
|
@ -40,8 +40,6 @@ import org.keycloak.services.managers.AuthenticationManager;
|
||||||
import org.keycloak.services.resources.Cors;
|
import org.keycloak.services.resources.Cors;
|
||||||
import org.keycloak.services.Urls;
|
import org.keycloak.services.Urls;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
|
||||||
import javax.ws.rs.FormParam;
|
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.OPTIONS;
|
import javax.ws.rs.OPTIONS;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
|
@ -105,9 +103,17 @@ public class UserInfoEndpoint {
|
||||||
@Path("/")
|
@Path("/")
|
||||||
@POST
|
@POST
|
||||||
@NoCache
|
@NoCache
|
||||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public Response issueUserInfoPost(@FormParam("access_token") String accessToken) {
|
public Response issueUserInfoPost() {
|
||||||
|
// Try header first
|
||||||
|
HttpHeaders headers = request.getHttpHeaders();
|
||||||
|
String accessToken = this.appAuthManager.extractAuthorizationHeaderToken(headers);
|
||||||
|
|
||||||
|
// Fallback to form parameter
|
||||||
|
if (accessToken == null) {
|
||||||
|
accessToken = request.getDecodedFormParameters().getFirst("access_token");
|
||||||
|
}
|
||||||
|
|
||||||
return issueUserInfo(accessToken);
|
return issueUserInfo(accessToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,57 +75,120 @@ public class UserInfoTest extends AbstractKeycloakTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSuccessfulUserInfoRequest() throws Exception {
|
public void testSuccess_getMethod_bearer() throws Exception {
|
||||||
Client client = ClientBuilder.newClient();
|
Client client = ClientBuilder.newClient();
|
||||||
UriBuilder builder = UriBuilder.fromUri(AUTH_SERVER_ROOT);
|
|
||||||
URI grantUri = OIDCLoginProtocolService.tokenUrl(builder).build("test");
|
|
||||||
WebTarget grantTarget = client.target(grantUri);
|
|
||||||
AccessTokenResponse accessTokenResponse = executeGrantAccessTokenRequest(grantTarget);
|
|
||||||
Response response = executeUserInfoRequest(accessTokenResponse.getToken());
|
|
||||||
|
|
||||||
assertEquals(Status.OK.getStatusCode(), response.getStatus());
|
try {
|
||||||
|
AccessTokenResponse accessTokenResponse = executeGrantAccessTokenRequest(client);
|
||||||
|
Response response = executeUserInfoRequest_getMethod(client, accessTokenResponse.getToken());
|
||||||
|
|
||||||
UserInfo userInfo = response.readEntity(UserInfo.class);
|
testSuccessfulUserInfoResponse(response);
|
||||||
|
|
||||||
response.close();
|
|
||||||
|
|
||||||
assertNotNull(userInfo);
|
|
||||||
assertNotNull(userInfo.getSubject());
|
|
||||||
assertEquals("test-user@localhost", userInfo.getEmail());
|
|
||||||
assertEquals("test-user@localhost", userInfo.getPreferredUsername());
|
|
||||||
|
|
||||||
|
} finally {
|
||||||
client.close();
|
client.close();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSuccess_postMethod_bearer() throws Exception {
|
||||||
|
Client client = ClientBuilder.newClient();
|
||||||
|
|
||||||
|
try {
|
||||||
|
AccessTokenResponse accessTokenResponse = executeGrantAccessTokenRequest(client);
|
||||||
|
|
||||||
|
WebTarget userInfoTarget = getUserInfoWebTarget(client);
|
||||||
|
Response response = userInfoTarget.request()
|
||||||
|
.header(HttpHeaders.AUTHORIZATION, "bearer " + accessTokenResponse.getToken())
|
||||||
|
.post(Entity.form(new Form()));
|
||||||
|
|
||||||
|
testSuccessfulUserInfoResponse(response);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSuccess_postMethod_body() throws Exception {
|
||||||
|
Client client = ClientBuilder.newClient();
|
||||||
|
|
||||||
|
try {
|
||||||
|
AccessTokenResponse accessTokenResponse = executeGrantAccessTokenRequest(client);
|
||||||
|
|
||||||
|
Form form = new Form();
|
||||||
|
form.param("access_token", accessTokenResponse.getToken());
|
||||||
|
|
||||||
|
WebTarget userInfoTarget = getUserInfoWebTarget(client);
|
||||||
|
Response response = userInfoTarget.request()
|
||||||
|
.post(Entity.form(form));
|
||||||
|
|
||||||
|
testSuccessfulUserInfoResponse(response);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSuccess_postMethod_bearer_textEntity() throws Exception {
|
||||||
|
Client client = ClientBuilder.newClient();
|
||||||
|
|
||||||
|
try {
|
||||||
|
AccessTokenResponse accessTokenResponse = executeGrantAccessTokenRequest(client);
|
||||||
|
|
||||||
|
WebTarget userInfoTarget = getUserInfoWebTarget(client);
|
||||||
|
Response response = userInfoTarget.request()
|
||||||
|
.header(HttpHeaders.AUTHORIZATION, "bearer " + accessTokenResponse.getToken())
|
||||||
|
.post(Entity.text(""));
|
||||||
|
|
||||||
|
testSuccessfulUserInfoResponse(response);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSessionExpired() throws Exception {
|
public void testSessionExpired() throws Exception {
|
||||||
Client client = ClientBuilder.newClient();
|
Client client = ClientBuilder.newClient();
|
||||||
UriBuilder builder = UriBuilder.fromUri(AUTH_SERVER_ROOT);
|
|
||||||
URI grantUri = OIDCLoginProtocolService.tokenUrl(builder).build("test");
|
try {
|
||||||
WebTarget grantTarget = client.target(grantUri);
|
AccessTokenResponse accessTokenResponse = executeGrantAccessTokenRequest(client);
|
||||||
AccessTokenResponse accessTokenResponse = executeGrantAccessTokenRequest(grantTarget);
|
|
||||||
|
|
||||||
testingClient.testing().removeUserSessions("test");
|
testingClient.testing().removeUserSessions("test");
|
||||||
|
|
||||||
Response response = executeUserInfoRequest(accessTokenResponse.getToken());
|
Response response = executeUserInfoRequest_getMethod(client, accessTokenResponse.getToken());
|
||||||
|
|
||||||
assertEquals(Status.FORBIDDEN.getStatusCode(), response.getStatus());
|
assertEquals(Status.FORBIDDEN.getStatusCode(), response.getStatus());
|
||||||
|
|
||||||
response.close();
|
response.close();
|
||||||
|
|
||||||
|
} finally {
|
||||||
client.close();
|
client.close();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUnsuccessfulUserInfoRequest() throws Exception {
|
public void testUnsuccessfulUserInfoRequest() throws Exception {
|
||||||
Response response = executeUserInfoRequest("bad");
|
Client client = ClientBuilder.newClient();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Response response = executeUserInfoRequest_getMethod(client, "bad");
|
||||||
|
|
||||||
response.close();
|
response.close();
|
||||||
|
|
||||||
assertEquals(Status.FORBIDDEN.getStatusCode(), response.getStatus());
|
assertEquals(Status.FORBIDDEN.getStatusCode(), response.getStatus());
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private AccessTokenResponse executeGrantAccessTokenRequest(WebTarget grantTarget) {
|
private AccessTokenResponse executeGrantAccessTokenRequest(Client client) {
|
||||||
|
UriBuilder builder = UriBuilder.fromUri(AUTH_SERVER_ROOT);
|
||||||
|
URI grantUri = OIDCLoginProtocolService.tokenUrl(builder).build("test");
|
||||||
|
WebTarget grantTarget = client.target(grantUri);
|
||||||
|
|
||||||
String header = BasicAuthHelper.createHeader("test-app", "password");
|
String header = BasicAuthHelper.createHeader("test-app", "password");
|
||||||
Form form = new Form();
|
Form form = new Form();
|
||||||
form.param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.PASSWORD)
|
form.param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.PASSWORD)
|
||||||
|
@ -145,15 +208,31 @@ public class UserInfoTest extends AbstractKeycloakTest {
|
||||||
return accessTokenResponse;
|
return accessTokenResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response executeUserInfoRequest(String accessToken) {
|
private Response executeUserInfoRequest_getMethod(Client client, String accessToken) {
|
||||||
UriBuilder builder = UriBuilder.fromUri(AUTH_SERVER_ROOT);
|
WebTarget userInfoTarget = getUserInfoWebTarget(client);
|
||||||
UriBuilder uriBuilder = OIDCLoginProtocolService.tokenServiceBaseUrl(builder);
|
|
||||||
URI userInfoUri = uriBuilder.path(OIDCLoginProtocolService.class, "issueUserInfo").build("test");
|
|
||||||
Client client = ClientBuilder.newClient();
|
|
||||||
WebTarget userInfoTarget = client.target(userInfoUri);
|
|
||||||
|
|
||||||
return userInfoTarget.request()
|
return userInfoTarget.request()
|
||||||
.header(HttpHeaders.AUTHORIZATION, "bearer " + accessToken)
|
.header(HttpHeaders.AUTHORIZATION, "bearer " + accessToken)
|
||||||
.get();
|
.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private WebTarget getUserInfoWebTarget(Client client) {
|
||||||
|
UriBuilder builder = UriBuilder.fromUri(AUTH_SERVER_ROOT);
|
||||||
|
UriBuilder uriBuilder = OIDCLoginProtocolService.tokenServiceBaseUrl(builder);
|
||||||
|
URI userInfoUri = uriBuilder.path(OIDCLoginProtocolService.class, "issueUserInfo").build("test");
|
||||||
|
return client.target(userInfoUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testSuccessfulUserInfoResponse(Response response) {
|
||||||
|
assertEquals(Status.OK.getStatusCode(), response.getStatus());
|
||||||
|
|
||||||
|
UserInfo userInfo = response.readEntity(UserInfo.class);
|
||||||
|
|
||||||
|
response.close();
|
||||||
|
|
||||||
|
assertNotNull(userInfo);
|
||||||
|
assertNotNull(userInfo.getSubject());
|
||||||
|
assertEquals("test-user@localhost", userInfo.getEmail());
|
||||||
|
assertEquals("test-user@localhost", userInfo.getPreferredUsername());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue