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:
parent
685acb786a
commit
a4315f4076
2 changed files with 30 additions and 11 deletions
|
@ -203,17 +203,6 @@ public class TokenManager {
|
||||||
return false;
|
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());
|
ClientModel client = realm.getClientByClientId(token.getIssuedFor());
|
||||||
if (client == null || !client.isEnabled() || token.getIssuedAt() < client.getNotBefore()) {
|
if (client == null || !client.isEnabled() || token.getIssuedAt() < client.getNotBefore()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -224,6 +213,16 @@ public class TokenManager {
|
||||||
return true;
|
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());
|
userSession = new UserSessionCrossDCManager(session).getUserSessionWithClient(realm, token.getSessionState(), true, client.getId());
|
||||||
if (AuthenticationManager.isOfflineSessionValid(realm, userSession)) {
|
if (AuthenticationManager.isOfflineSessionValid(realm, userSession)) {
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
package org.keycloak.testsuite.client;
|
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.apache.commons.lang.StringUtils;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
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.OAuthClient;
|
||||||
import org.keycloak.testsuite.util.UserInfoClientUtil;
|
import org.keycloak.testsuite.util.UserInfoClientUtil;
|
||||||
import org.keycloak.testsuite.util.UserManager;
|
import org.keycloak.testsuite.util.UserManager;
|
||||||
|
import org.keycloak.util.JsonSerialization;
|
||||||
|
|
||||||
import javax.ws.rs.client.Client;
|
import javax.ws.rs.client.Client;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -407,6 +411,22 @@ public class OIDCPairwiseClientRegistrationTest extends AbstractClientRegistrati
|
||||||
Assert.assertEquals(idToken.getIssuedFor(), refreshedIdToken.getIssuedFor());
|
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
|
@Test
|
||||||
public void refreshPairwiseTokenDeletedUser() throws Exception {
|
public void refreshPairwiseTokenDeletedUser() throws Exception {
|
||||||
String userId = createUser(REALM_NAME, "delete-me@localhost", "password");
|
String userId = createUser(REALM_NAME, "delete-me@localhost", "password");
|
||||||
|
|
Loading…
Reference in a new issue