KEYCLOAK-3701 NullPointerException when trying to get access token from offline token

This commit is contained in:
mposolda 2016-12-02 16:35:08 +01:00
parent 8842d88058
commit cccb532a21
4 changed files with 23 additions and 23 deletions

View file

@ -38,6 +38,7 @@ import org.keycloak.models.GroupModel;
import org.keycloak.models.KeyManager; import org.keycloak.models.KeyManager;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.ModelException;
import org.keycloak.models.ProtocolMapperModel; import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
@ -130,15 +131,24 @@ public class TokenManager {
if (TokenUtil.TOKEN_TYPE_OFFLINE.equals(oldToken.getType())) { if (TokenUtil.TOKEN_TYPE_OFFLINE.equals(oldToken.getType())) {
UserSessionManager sessionManager = new UserSessionManager(session); UserSessionManager sessionManager = new UserSessionManager(session);
clientSession = sessionManager.findOfflineClientSession(realm, oldToken.getClientSession(), oldToken.getSessionState()); clientSession = sessionManager.findOfflineClientSession(realm, oldToken.getClientSession());
if (clientSession != null) { if (clientSession != null) {
userSession = clientSession.getUserSession(); userSession = clientSession.getUserSession();
if (userSession == null) {
throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Offline user session not found", "Offline user session not found");
}
String userSessionId = oldToken.getSessionState();
if (!userSessionId.equals(userSession.getId())) {
throw new ModelException("User session don't match. Offline client session " + clientSession.getId() + ", It's user session " + userSession.getId() +
" Wanted user session: " + userSessionId);
}
// Revoke timeouted offline userSession // Revoke timeouted offline userSession
if (userSession.getLastSessionRefresh() < Time.currentTime() - realm.getOfflineSessionIdleTimeout()) { if (userSession.getLastSessionRefresh() < Time.currentTime() - realm.getOfflineSessionIdleTimeout()) {
sessionManager.revokeOfflineUserSession(userSession); sessionManager.revokeOfflineUserSession(userSession);
userSession = null; throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Offline user session not active", "Offline user session session not active");
clientSession = null;
} }
} }
} else { } else {

View file

@ -72,18 +72,8 @@ public class UserSessionManager {
} }
// userSessionId is provided from offline token. It's used just to verify if it match the ID from clientSession representation // userSessionId is provided from offline token. It's used just to verify if it match the ID from clientSession representation
public ClientSessionModel findOfflineClientSession(RealmModel realm, String clientSessionId, String userSessionId) { public ClientSessionModel findOfflineClientSession(RealmModel realm, String clientSessionId) {
ClientSessionModel clientSession = kcSession.sessions().getOfflineClientSession(realm, clientSessionId); return kcSession.sessions().getOfflineClientSession(realm, clientSessionId);
if (clientSession == null) {
return null;
}
if (!userSessionId.equals(clientSession.getUserSession().getId())) {
throw new ModelException("User session don't match. Offline client session " + clientSession.getId() + ", It's user session " + clientSession.getUserSession().getId() +
" Wanted user session: " + userSessionId);
}
return clientSession;
} }
public Set<ClientModel> findClientsWithOfflineToken(RealmModel realm, UserModel user) { public Set<ClientModel> findClientsWithOfflineToken(RealmModel realm, UserModel user) {

View file

@ -285,7 +285,7 @@ public class OfflineTokenTest extends AbstractKeycloakTest {
oauth.scope(OAuth2Constants.OFFLINE_ACCESS); oauth.scope(OAuth2Constants.OFFLINE_ACCESS);
oauth.clientId("offline-client"); oauth.clientId("offline-client");
OAuthClient.AccessTokenResponse tokenResponse = oauth.doGrantAccessTokenRequest("secret1", "test-user@localhost", "password"); OAuthClient.AccessTokenResponse tokenResponse = oauth.doGrantAccessTokenRequest("secret1", "test-user@localhost", "password");
tokenResponse.getErrorDescription(); Assert.assertNull(tokenResponse.getErrorDescription());
AccessToken token = oauth.verifyToken(tokenResponse.getAccessToken()); AccessToken token = oauth.verifyToken(tokenResponse.getAccessToken());
String offlineTokenString = tokenResponse.getRefreshToken(); String offlineTokenString = tokenResponse.getRefreshToken();
RefreshToken offlineToken = oauth.verifyRefreshToken(offlineTokenString); RefreshToken offlineToken = oauth.verifyRefreshToken(offlineTokenString);

View file

@ -107,7 +107,7 @@ public class UserSessionProviderOfflineTest {
// Assert all previously saved offline sessions found // Assert all previously saved offline sessions found
for (Map.Entry<String, String> entry : offlineSessions.entrySet()) { for (Map.Entry<String, String> entry : offlineSessions.entrySet()) {
Assert.assertTrue(sessionManager.findOfflineClientSession(realm, entry.getKey(), entry.getValue()) != null); Assert.assertTrue(sessionManager.findOfflineClientSession(realm, entry.getKey()) != null);
UserSessionModel offlineSession = session.sessions().getUserSession(realm, entry.getValue()); UserSessionModel offlineSession = session.sessions().getUserSession(realm, entry.getValue());
boolean found = false; boolean found = false;
@ -187,7 +187,7 @@ public class UserSessionProviderOfflineTest {
resetSession(); resetSession();
ClientSessionModel offlineClientSession = sessionManager.findOfflineClientSession(fooRealm, clientSession.getId(), userSession.getId()); ClientSessionModel offlineClientSession = sessionManager.findOfflineClientSession(fooRealm, clientSession.getId());
Assert.assertEquals("foo-app", offlineClientSession.getClient().getClientId()); Assert.assertEquals("foo-app", offlineClientSession.getClient().getClientId());
Assert.assertEquals("user3", offlineClientSession.getUserSession().getUser().getUsername()); Assert.assertEquals("user3", offlineClientSession.getUserSession().getUser().getUsername());
Assert.assertEquals(offlineClientSession.getId(), offlineClientSession.getUserSession().getClientSessions().get(0).getId()); Assert.assertEquals(offlineClientSession.getId(), offlineClientSession.getUserSession().getClientSessions().get(0).getId());
@ -206,7 +206,7 @@ public class UserSessionProviderOfflineTest {
// Assert nothing loaded // Assert nothing loaded
fooRealm = session.realms().getRealm("foo"); fooRealm = session.realms().getRealm("foo");
Assert.assertNull(sessionManager.findOfflineClientSession(fooRealm, clientSession.getId(), userSession.getId())); Assert.assertNull(sessionManager.findOfflineClientSession(fooRealm, clientSession.getId()));
Assert.assertEquals(0, session.sessions().getOfflineSessionsCount(fooRealm, fooRealm.getClientByClientId("foo-app"))); Assert.assertEquals(0, session.sessions().getOfflineSessionsCount(fooRealm, fooRealm.getClientByClientId("foo-app")));
// Cleanup // Cleanup
@ -338,7 +338,7 @@ public class UserSessionProviderOfflineTest {
// Assert all previously saved offline sessions found // Assert all previously saved offline sessions found
for (Map.Entry<String, String> entry : offlineSessions.entrySet()) { for (Map.Entry<String, String> entry : offlineSessions.entrySet()) {
Assert.assertTrue(sessionManager.findOfflineClientSession(realm, entry.getKey(), entry.getValue()) != null); Assert.assertTrue(sessionManager.findOfflineClientSession(realm, entry.getKey()) != null);
} }
UserSessionModel session0 = session.sessions().getOfflineUserSession(realm, origSessions[0].getId()); UserSessionModel session0 = session.sessions().getOfflineUserSession(realm, origSessions[0].getId());
@ -379,9 +379,9 @@ public class UserSessionProviderOfflineTest {
for (Map.Entry<String, String> entry : offlineSessions.entrySet()) { for (Map.Entry<String, String> entry : offlineSessions.entrySet()) {
String userSessionId = entry.getValue(); String userSessionId = entry.getValue();
if (userSessionId.equals(session1.getId())) { if (userSessionId.equals(session1.getId())) {
Assert.assertFalse(sessionManager.findOfflineClientSession(realm, entry.getKey(), userSessionId) != null); Assert.assertFalse(sessionManager.findOfflineClientSession(realm, entry.getKey()) != null);
} else { } else {
Assert.assertTrue(sessionManager.findOfflineClientSession(realm, entry.getKey(), userSessionId) != null); Assert.assertTrue(sessionManager.findOfflineClientSession(realm, entry.getKey()) != null);
} }
} }
Assert.assertEquals(1, persister.getUserSessionsCount(true)); Assert.assertEquals(1, persister.getUserSessionsCount(true));
@ -394,7 +394,7 @@ public class UserSessionProviderOfflineTest {
resetSession(); resetSession();
for (Map.Entry<String, String> entry : offlineSessions.entrySet()) { for (Map.Entry<String, String> entry : offlineSessions.entrySet()) {
Assert.assertTrue(sessionManager.findOfflineClientSession(realm, entry.getKey(), entry.getValue()) == null); Assert.assertTrue(sessionManager.findOfflineClientSession(realm, entry.getKey()) == null);
} }
Assert.assertEquals(0, persister.getUserSessionsCount(true)); Assert.assertEquals(0, persister.getUserSessionsCount(true));