From d5c643eaf9b4263191ba11c4cda08dfaacfac1ea Mon Sep 17 00:00:00 2001 From: Marc Heide Date: Thu, 4 May 2017 15:25:09 +0200 Subject: [PATCH] KEYCLOAK-4521: consider offline sessions if no active user session was found for user info endpoint --- .../oidc/endpoints/UserInfoEndpoint.java | 9 +++++++ .../keycloak/testsuite/oidc/UserInfoTest.java | 27 ++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/UserInfoEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/UserInfoEndpoint.java index 1014c0bcc9..8984a4db56 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/UserInfoEndpoint.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/UserInfoEndpoint.java @@ -141,6 +141,15 @@ public class UserInfoEndpoint { UserSessionModel userSession = session.sessions().getUserSession(realm, token.getSessionState()); ClientSessionModel clientSession = session.sessions().getClientSession(token.getClientSession()); + if( userSession == null ) { + userSession = session.sessions().getOfflineUserSession(realm, token.getSessionState()); + if( AuthenticationManager.isOfflineSessionValid(realm, userSession)) { + clientSession = session.sessions().getOfflineClientSession(realm, token.getClientSession()); + } else { + userSession = null; + clientSession = null; + } + } if (userSession == null) { event.error(Errors.USER_SESSION_NOT_FOUND); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/UserInfoTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/UserInfoTest.java index e6ec392e6e..c57b64e3a0 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/UserInfoTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/UserInfoTest.java @@ -249,6 +249,24 @@ public class UserInfoTest extends AbstractKeycloakTest { } } + @Test + public void testSessionExpiredOfflineAccess() throws Exception { + Client client = ClientBuilder.newClient(); + + try { + AccessTokenResponse accessTokenResponse = executeGrantAccessTokenRequest(client, true); + + testingClient.testing().removeUserSessions("test"); + + Response response = UserInfoClientUtil.executeUserInfoRequest_getMethod(client, accessTokenResponse.getToken()); + + testSuccessfulUserInfoResponse(response); + response.close(); + } finally { + client.close(); + } + } + @Test public void testUnsuccessfulUserInfoRequest() throws Exception { Client client = ClientBuilder.newClient(); @@ -274,8 +292,12 @@ public class UserInfoTest extends AbstractKeycloakTest { } private AccessTokenResponse executeGrantAccessTokenRequest(Client client) { + return executeGrantAccessTokenRequest(client, false); + } + + private AccessTokenResponse executeGrantAccessTokenRequest(Client client, boolean requestOfflineToken) { UriBuilder builder = UriBuilder.fromUri(AUTH_SERVER_ROOT); - URI grantUri = OIDCLoginProtocolService.tokenUrl(builder).build("test"); + URI grantUri = OIDCLoginProtocolService.tokenUrl(builder).build("test"); WebTarget grantTarget = client.target(grantUri); String header = BasicAuthHelper.createHeader("test-app", "password"); @@ -283,6 +305,9 @@ public class UserInfoTest extends AbstractKeycloakTest { form.param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.PASSWORD) .param("username", "test-user@localhost") .param("password", "password"); + if( requestOfflineToken) { + form.param("scope", "offline_access"); + } Response response = grantTarget.request() .header(HttpHeaders.AUTHORIZATION, header)