Fix introspection error for pairwise access tokens

When access tokens containing a pairwise sub are introspected, user
related checks are using that sub to fetch the UserModel instead of
fetching the user from the UserSession. No corresponding user is found
(or possibly even another user) and the token is reported inactive.

Resolves: KEYCLOAK-5494
This commit is contained in:
Martin Hardselius 2017-09-15 10:17:45 +02:00
parent 685acb786a
commit a4315f4076
2 changed files with 30 additions and 11 deletions

View file

@ -203,17 +203,6 @@ public class TokenManager {
return false;
}
UserModel user = session.users().getUserById(token.getSubject(), realm);
if (user == null) {
return false;
}
if (!user.isEnabled()) {
return false;
}
if (token.getIssuedAt() < session.users().getNotBeforeOfUser(realm, user)) {
return false;
}
ClientModel client = realm.getClientByClientId(token.getIssuedFor());
if (client == null || !client.isEnabled() || token.getIssuedAt() < client.getNotBefore()) {
return false;
@ -224,6 +213,16 @@ public class TokenManager {
return true;
}
UserModel user = userSession.getUser();
if (user == null) {
return false;
}
if (!user.isEnabled()) {
return false;
}
if (token.getIssuedAt() < session.users().getNotBeforeOfUser(realm, user)) {
return false;
}
userSession = new UserSessionCrossDCManager(session).getUserSessionWithClient(realm, token.getSessionState(), true, client.getId());
if (AuthenticationManager.isOfflineSessionValid(realm, userSession)) {

View file

@ -18,6 +18,8 @@
package org.keycloak.testsuite.client;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang.StringUtils;
import org.junit.Before;
import org.junit.Test;
@ -44,9 +46,11 @@ import org.keycloak.testsuite.util.ClientManager;
import org.keycloak.testsuite.util.OAuthClient;
import org.keycloak.testsuite.util.UserInfoClientUtil;
import org.keycloak.testsuite.util.UserManager;
import org.keycloak.util.JsonSerialization;
import javax.ws.rs.client.Client;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collections;
@ -407,6 +411,22 @@ public class OIDCPairwiseClientRegistrationTest extends AbstractClientRegistrati
Assert.assertEquals(idToken.getIssuedFor(), refreshedIdToken.getIssuedFor());
}
@Test
public void introspectPairwiseAccessToken() throws Exception {
// Create a pairwise client
OIDCClientRepresentation pairwiseClient = createPairwise();
// Login to pairwise client
OAuthClient.AccessTokenResponse accessTokenResponse = login(pairwiseClient, "test-user@localhost", "password");
String introspectionResponse = oauth.introspectAccessTokenWithClientCredential(pairwiseClient.getClientId(), pairwiseClient.getClientSecret(), accessTokenResponse.getAccessToken());
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(introspectionResponse);
Assert.assertEquals(true, jsonNode.get("active").asBoolean());
Assert.assertEquals("test-user@localhost", jsonNode.get("email").asText());
}
@Test
public void refreshPairwiseTokenDeletedUser() throws Exception {
String userId = createUser(REALM_NAME, "delete-me@localhost", "password");