keycloak-uncached

Merge pull request #4134 from stianst/2.5.x KEYCLOAK-4521:

5/12/2017 6:03:10 AM

Details

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 1014c0b..8984a4d 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 e6ec392..c57b64e 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
@@ -250,6 +250,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)