keycloak-uncached

KEYCLOAK-4829 Access token from offline token falsely reported

5/11/2017 4:17:04 PM

Details

diff --git a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
index 5e1e247..4cedd6b 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
@@ -214,16 +214,22 @@ public class TokenManager {
         }
 
         UserSessionModel userSession =  session.sessions().getUserSession(realm, token.getSessionState());
-        if (!AuthenticationManager.isSessionValid(realm, userSession)) {
-            return false;
+        if (AuthenticationManager.isSessionValid(realm, userSession)) {
+            ClientSessionModel clientSession = session.sessions().getClientSession(realm, token.getClientSession());
+            if (clientSession != null) {
+                return true;
+            }
         }
 
-        ClientSessionModel clientSession = session.sessions().getClientSession(realm, token.getClientSession());
-        if (clientSession == null) {
-            return false;
+        userSession = session.sessions().getOfflineUserSession(realm, token.getSessionState());
+        if (AuthenticationManager.isOfflineSessionValid(realm, userSession)) {
+            ClientSessionModel clientSession = session.sessions().getOfflineClientSession(realm, token.getClientSession());
+            if (clientSession != null) {
+                return true;
+            }
         }
 
-        return true;
+        return false;
     }
 
     public RefreshResult refreshAccessToken(KeycloakSession session, UriInfo uriInfo, ClientConnection connection, RealmModel realm, ClientModel authorizedClient, String encodedRefreshToken, EventBuilder event, HttpHeaders headers) throws OAuthErrorException {
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/TokenIntrospectionTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/TokenIntrospectionTest.java
index ee700dc..114b70e 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/TokenIntrospectionTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/TokenIntrospectionTest.java
@@ -237,6 +237,38 @@ public class TokenIntrospectionTest extends AbstractTestRealmKeycloakTest {
         assertNull(rep.getSubject());
     }
 
+    // KEYCLOAK-4829
+    @Test
+    public void testIntrospectAccessTokenOfflineAccess() throws Exception {
+        oauth.scope(OAuth2Constants.OFFLINE_ACCESS);
+        oauth.doLogin("test-user@localhost", "password");
+        String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
+        AccessTokenResponse accessTokenResponse = oauth.doAccessTokenRequest(code, "password");
+
+        setTimeOffset(86400);
+
+        // "Online" session still exists, but is invalid
+        accessTokenResponse = oauth.doRefreshTokenRequest(accessTokenResponse.getRefreshToken(), "password");
+        String tokenResponse = oauth.introspectAccessTokenWithClientCredential("confidential-cli", "secret1", accessTokenResponse.getAccessToken());
+        TokenMetadataRepresentation rep = JsonSerialization.readValue(tokenResponse, TokenMetadataRepresentation.class);
+
+        assertTrue(rep.isActive());
+        assertEquals("test-user@localhost", rep.getUserName());
+        assertEquals("test-app", rep.getClientId());
+
+        // "Online" session doesn't even exists
+        testingClient.testing().removeExpired("test");
+
+        accessTokenResponse = oauth.doRefreshTokenRequest(accessTokenResponse.getRefreshToken(), "password");
+        tokenResponse = oauth.introspectAccessTokenWithClientCredential("confidential-cli", "secret1", accessTokenResponse.getAccessToken());
+        rep = JsonSerialization.readValue(tokenResponse, TokenMetadataRepresentation.class);
+
+        assertTrue(rep.isActive());
+        assertEquals("test-user@localhost", rep.getUserName());
+        assertEquals("test-app", rep.getClientId());
+    }
+
+
     @Test
     public void testIntrospectAccessTokenUserDisabled() throws Exception {
         oauth.doLogin("test-user@localhost", "password");