keycloak-uncached
Changes
core/src/main/java/org/keycloak/representations/idm/OfflineClientSessionRepresentation.java 35(+0 -35)
core/src/main/java/org/keycloak/representations/idm/OfflineUserSessionRepresentation.java 37(+0 -37)
examples/demo-template/offline-access-app/src/main/java/org/keycloak/example/OfflineAccessPortalServlet.java 4(+4 -0)
Details
diff --git a/core/src/main/java/org/keycloak/representations/idm/UserRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/UserRepresentation.java
index ee96b04..07865db 100755
--- a/core/src/main/java/org/keycloak/representations/idm/UserRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/UserRepresentation.java
@@ -34,7 +34,6 @@ public class UserRepresentation {
protected List<String> realmRoles;
protected Map<String, List<String>> clientRoles;
protected List<UserConsentRepresentation> clientConsents;
- protected List<OfflineUserSessionRepresentation> offlineUserSessions;
@Deprecated
protected Map<String, List<String>> applicationRoles;
@@ -217,12 +216,4 @@ public class UserRepresentation {
public void setServiceAccountClientId(String serviceAccountClientId) {
this.serviceAccountClientId = serviceAccountClientId;
}
-
- public List<OfflineUserSessionRepresentation> getOfflineUserSessions() {
- return offlineUserSessions;
- }
-
- public void setOfflineUserSessions(List<OfflineUserSessionRepresentation> offlineUserSessions) {
- this.offlineUserSessions = offlineUserSessions;
- }
}
diff --git a/docbook/auth-server-docs/reference/en/en-US/modules/MigrationFromOlderVersions.xml b/docbook/auth-server-docs/reference/en/en-US/modules/MigrationFromOlderVersions.xml
index 25a393f..650ed76 100755
--- a/docbook/auth-server-docs/reference/en/en-US/modules/MigrationFromOlderVersions.xml
+++ b/docbook/auth-server-docs/reference/en/en-US/modules/MigrationFromOlderVersions.xml
@@ -91,6 +91,31 @@
settings.
</para>
</simplesect>
+ <simplesect>
+ <title>Some packages renamed</title>
+ <para>
+ We did a bit of restructure and renamed some packages. It is mainly about renaming internal packages of util classes.
+ The most important classes used in your application ( for example AccessToken or KeycloakSecurityContext ) as well
+ as the SPI are still unchanged. However there is slight chance that you will be affected and will need to update imports of your classes.
+ For example if you are using multitenancy and KeycloakConfigResolver, you will be affected as for example class
+ HttpFacade was moved to different package - it is <literal>org.keycloak.adapters.spi.HttpFacade</literal> now.
+ </para>
+ </simplesect>
+ <simplesect>
+ <title>Persisting user sessions</title>
+ <para>
+ We added support for offline tokens in this release, which means that we are persisting "offline" user sessions into database now.
+ If you are not using offline tokens, nothing will be persisted for you, so you don't need to care about worse performance for more DB writes.
+ However in all cases, you will need to update <literal>standalone/configuration/keycloak-server.json</literal> and add <literal>userSessionPersister</literal>
+ like this:
+<programlisting>
+"userSessionPersister": {
+ "provider": "jpa"
+},
+</programlisting>
+ If you want sessions to be persisted in Mongo instead of classic RDBMS, use provider <literal>mongo</literal> instead.
+ </para>
+ </simplesect>
</section>
<section>
<title>Migrating to 1.5.0.Final</title>
diff --git a/docbook/auth-server-docs/reference/en/en-US/modules/timeouts.xml b/docbook/auth-server-docs/reference/en/en-US/modules/timeouts.xml
index 78418cb..7f8800e 100755
--- a/docbook/auth-server-docs/reference/en/en-US/modules/timeouts.xml
+++ b/docbook/auth-server-docs/reference/en/en-US/modules/timeouts.xml
@@ -67,7 +67,12 @@
</para>
<para>
The difference between classic Refresh token and Offline token is, that offline token will never expire and is not subject of <literal>SSO Session Idle timeout</literal> .
- The offline token is valid even after user logout or server restart. User can revoke the offline tokens in Account management UI. The admin
+ The offline token is valid even after user logout or server restart. However you need to use offline token for refresh at least once per each 30 days (
+ The value can be changed in admin console. It is <literal>Offline Session Idle timeout</literal> ). Also if you enable option <literal>Revoke refresh tokens</literal>
+ , then each offline token can be used just once. So after refresh, you always need to store new offline token from refresh response into your DB instead of the previous one.
+ </para>
+ <para>
+ User can revoke the offline tokens in Account management UI. The admin
user can revoke offline tokens for individual users in admin console (The <literal>Consent</literal> tab of particular user) and he can
see all the offline tokens of all users for particular client application in the settings of the client. Revoking of all offline tokens for particular
client is possible by set <literal>notBefore</literal> policy for the client.
diff --git a/examples/demo-template/offline-access-app/src/main/java/org/keycloak/example/OfflineAccessPortalServlet.java b/examples/demo-template/offline-access-app/src/main/java/org/keycloak/example/OfflineAccessPortalServlet.java
index ec791d1..8290b3b 100644
--- a/examples/demo-template/offline-access-app/src/main/java/org/keycloak/example/OfflineAccessPortalServlet.java
+++ b/examples/demo-template/offline-access-app/src/main/java/org/keycloak/example/OfflineAccessPortalServlet.java
@@ -98,6 +98,10 @@ public class OfflineAccessPortalServlet extends HttpServlet {
KeycloakDeployment deployment = getDeployment(req);
AccessTokenResponse response = ServerRequest.invokeRefresh(deployment, refreshToken);
accessToken = response.getToken();
+
+ // Uncomment this when you use revokeRefreshToken for realm. In that case each offline token can be used just once. So at this point, you need to
+ // save new offline token into DB
+ // RefreshTokenDAO.saveToken(response.getRefreshToken());
} catch (ServerRequest.HttpFailure failure) {
return "Failed to refresh token. Status from auth-server request: " + failure.getStatus() + ", Error: " + failure.getError();
}
diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java
index 6073e57..30eb055 100755
--- a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java
+++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java
@@ -294,28 +294,6 @@ public class ExportUtils {
}
}
-// // Offline sessions
-// List<OfflineUserSessionRepresentation> offlineSessionReps = new LinkedList<>();
-// Collection<PersistentUserSessionModel> offlineSessions = session.users().getOfflineUserSessions(realm, user);
-// Collection<PersistentClientSessionModel> offlineClientSessions = session.users().getOfflineClientSessions(realm, user);
-//
-// Map<String, List<PersistentClientSessionModel>> processed = new HashMap<>();
-// for (PersistentClientSessionModel clsm : offlineClientSessions) {
-// String userSessionId = clsm.getUserSessionId();
-// List<PersistentClientSessionModel> current = processed.get(userSessionId);
-// if (current == null) {
-// current = new LinkedList<>();
-// processed.put(userSessionId, current);
-// }
-// current.add(clsm);
-// }
-//
-// for (PersistentUserSessionModel userSession : offlineSessions) {
-// OfflineUserSessionRepresentation sessionRep = ModelToRepresentation.toRepresentation(realm, userSession, processed.get(userSession.getUserSessionId()));
-// offlineSessionReps.add(sessionRep);
-// }
-// userRep.setOfflineUserSessions(offlineSessionReps);
-
return userRep;
}
diff --git a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
index 732444e..5fcb826 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
@@ -32,8 +32,6 @@ import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.FederatedIdentityRepresentation;
import org.keycloak.representations.idm.IdentityProviderMapperRepresentation;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
-import org.keycloak.representations.idm.OfflineClientSessionRepresentation;
-import org.keycloak.representations.idm.OfflineUserSessionRepresentation;
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
import org.keycloak.representations.idm.RealmEventsConfigRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
@@ -517,33 +515,4 @@ public class ModelToRepresentation {
return rep;
}
- public static OfflineUserSessionRepresentation toRepresentation(RealmModel realm, PersistentUserSessionModel model, Collection<PersistentClientSessionModel> clientSessions) {
- OfflineUserSessionRepresentation rep = new OfflineUserSessionRepresentation();
- rep.setData(model.getData());
- rep.setUserSessionId(model.getUserSessionId());
-
- List<OfflineClientSessionRepresentation> clientSessionReps = new LinkedList<>();
- for (PersistentClientSessionModel clsm : clientSessions) {
- OfflineClientSessionRepresentation clrep = toRepresentation(realm, clsm);
- clientSessionReps.add(clrep);
- }
- rep.setOfflineClientSessions(clientSessionReps);
- return rep;
- }
-
- public static OfflineClientSessionRepresentation toRepresentation(RealmModel realm, PersistentClientSessionModel model) {
- OfflineClientSessionRepresentation rep = new OfflineClientSessionRepresentation();
-
- String clientInternalId = model.getClientId();
- ClientModel client = realm.getClientById(clientInternalId);
- rep.setClient(client.getClientId());
-
- rep.setClientSessionId(model.getClientSessionId());
- rep.setData(model.getData());
- return rep;
- }
-
-
-
-
}
diff --git a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
index 025ac8a..85b4ac0 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
@@ -1161,30 +1161,6 @@ public class RepresentationToModel {
return consentModel;
}
- // TODO
-// public static void importOfflineSession(KeycloakSession session, RealmModel newRealm, UserModel user, OfflineUserSessionRepresentation sessionRep) {
-// PersistentUserSessionModel model = new PersistentUserSessionModel();
-// model.setUserSessionId(sessionRep.getUserSessionId());
-// model.setData(sessionRep.getData());
-// session.users().createOfflineUserSession(newRealm, user, model);
-//
-// for (OfflineClientSessionRepresentation csRep : sessionRep.getOfflineClientSessions()) {
-// PersistentClientSessionModel csModel = new PersistentClientSessionModel();
-// String clientId = csRep.getClient();
-// ClientModel client = newRealm.getClientByClientId(clientId);
-// if (client == null) {
-// throw new RuntimeException("Unable to find client " + clientId + " referenced from offlineClientSession of user " + user.getUsername());
-// }
-// csModel.setClientId(client.getId());
-// csModel.setUserId(user.getId());
-// csModel.setClientSessionId(csRep.getClientSessionId());
-// csModel.setUserSessionId(sessionRep.getUserSessionId());
-// csModel.setData(csRep.getData());
-//
-// session.users().createOfflineClientSession(newRealm, csModel);
-// }
-// }
-
public static AuthenticationFlowModel toModel(AuthenticationFlowRepresentation rep) {
AuthenticationFlowModel model = new AuthenticationFlowModel();
model.setBuiltIn(rep.isBuiltIn());
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/session/PersistentClientSessionEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/session/PersistentClientSessionEntity.java
index faf3f80..51a5239 100644
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/session/PersistentClientSessionEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/session/PersistentClientSessionEntity.java
@@ -20,10 +20,10 @@ import javax.persistence.Table;
@NamedQuery(name="deleteClientSessionsByRealm", query="delete from PersistentClientSessionEntity sess where sess.userSessionId IN (select u.userSessionId from PersistentUserSessionEntity u where u.realmId=:realmId)"),
@NamedQuery(name="deleteClientSessionsByClient", query="delete from PersistentClientSessionEntity sess where sess.clientId=:clientId"),
@NamedQuery(name="deleteClientSessionsByUser", query="delete from PersistentClientSessionEntity sess where sess.userSessionId IN (select u.userSessionId from PersistentUserSessionEntity u where u.userId=:userId)"),
- @NamedQuery(name="deleteClientSessionsByUserSession", query="delete from PersistentClientSessionEntity sess where sess.userSessionId=:userSessionId and offline=:offline"),
+ @NamedQuery(name="deleteClientSessionsByUserSession", query="delete from PersistentClientSessionEntity sess where sess.userSessionId=:userSessionId and sess.offline=:offline"),
@NamedQuery(name="deleteDetachedClientSessions", query="delete from PersistentClientSessionEntity sess where sess.userSessionId NOT IN (select u.userSessionId from PersistentUserSessionEntity u)"),
- @NamedQuery(name="findClientSessionsByUserSession", query="select sess from PersistentClientSessionEntity sess where sess.userSessionId=:userSessionId and offline=:offline"),
- @NamedQuery(name="findClientSessionsByUserSessions", query="select sess from PersistentClientSessionEntity sess where offline=:offline and sess.userSessionId IN (:userSessionIds) order by sess.userSessionId"),
+ @NamedQuery(name="findClientSessionsByUserSession", query="select sess from PersistentClientSessionEntity sess where sess.userSessionId=:userSessionId and sess.offline=:offline"),
+ @NamedQuery(name="findClientSessionsByUserSessions", query="select sess from PersistentClientSessionEntity sess where sess.offline=:offline and sess.userSessionId IN (:userSessionIds) order by sess.userSessionId"),
@NamedQuery(name="updateClientSessionsTimestamps", query="update PersistentClientSessionEntity c set timestamp=:timestamp"),
})
@Table(name="OFFLINE_CLIENT_SESSION")
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/session/PersistentUserSessionEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/session/PersistentUserSessionEntity.java
index 95745a8..f56284c 100644
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/session/PersistentUserSessionEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/session/PersistentUserSessionEntity.java
@@ -25,8 +25,8 @@ import org.keycloak.models.jpa.entities.UserEntity;
@NamedQuery(name="deleteUserSessionsByRealm", query="delete from PersistentUserSessionEntity sess where sess.realmId=:realmId"),
@NamedQuery(name="deleteUserSessionsByUser", query="delete from PersistentUserSessionEntity sess where sess.userId=:userId"),
@NamedQuery(name="deleteDetachedUserSessions", query="delete from PersistentUserSessionEntity sess where sess.userSessionId NOT IN (select c.userSessionId from PersistentClientSessionEntity c)"),
- @NamedQuery(name="findUserSessionsCount", query="select count(sess) from PersistentUserSessionEntity sess where offline=:offline"),
- @NamedQuery(name="findUserSessions", query="select sess from PersistentUserSessionEntity sess where offline=:offline order by sess.userSessionId"),
+ @NamedQuery(name="findUserSessionsCount", query="select count(sess) from PersistentUserSessionEntity sess where sess.offline=:offline"),
+ @NamedQuery(name="findUserSessions", query="select sess from PersistentUserSessionEntity sess where sess.offline=:offline order by sess.userSessionId"),
@NamedQuery(name="updateUserSessionsTimestamps", query="update PersistentUserSessionEntity c set lastSessionRefresh=:lastSessionRefresh"),
})
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java
index bbc840e..b2d14b9 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java
@@ -327,21 +327,6 @@ public class ImportTest extends AbstractModelTest {
Assert.assertFalse(otherAppAdminConsent.isRoleGranted(application.getRole("app-admin")));
Assert.assertTrue(otherAppAdminConsent.isProtocolMapperGranted(gssCredentialMapper));
-// // Test offline sessions
-// Collection<PersistentUserSessionModel> offlineUserSessions = session.users().getOfflineUserSessions(realm, admin);
-// Collection<PersistentClientSessionModel> offlineClientSessions = session.users().getOfflineClientSessions(realm, admin);
-// Assert.assertEquals(offlineUserSessions.size(), 1);
-// Assert.assertEquals(offlineClientSessions.size(), 1);
-// PersistentUserSessionModel offlineSession = offlineUserSessions.iterator().next();
-// PersistentClientSessionModel offlineClSession = offlineClientSessions.iterator().next();
-// Assert.assertEquals(offlineSession.getData(), "something1");
-// Assert.assertEquals(offlineSession.getUserSessionId(), "123");
-// Assert.assertEquals(offlineClSession.getClientId(), otherApp.getId());
-// Assert.assertEquals(offlineClSession.getUserSessionId(), "123");
-// Assert.assertEquals(offlineClSession.getUserId(), admin.getId());
-// Assert.assertEquals(offlineClSession.getData(), "something2");
-
-
// Test service accounts
Assert.assertFalse(application.isServiceAccountsEnabled());
Assert.assertTrue(otherApp.isServiceAccountsEnabled());
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserModelTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserModelTest.java
index fee7bde..258dd3c 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserModelTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserModelTest.java
@@ -4,8 +4,6 @@ import org.junit.Assert;
import org.junit.Test;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.session.PersistentClientSessionModel;
-import org.keycloak.models.session.PersistentUserSessionModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserModel.RequiredAction;
@@ -15,7 +13,6 @@ import static org.junit.Assert.assertNotNull;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -286,83 +283,6 @@ public class UserModelTest extends AbstractModelTest {
Assert.assertNull(session.users().getUserByUsername("user1", realm));
}
-// @Test
-// public void testOfflineSessionsRemoved() {
-// RealmModel realm = realmManager.createRealm("original");
-// ClientModel fooClient = realm.addClient("foo");
-// ClientModel barClient = realm.addClient("bar");
-//
-// UserModel user1 = session.users().addUser(realm, "user1");
-// UserModel user2 = session.users().addUser(realm, "user2");
-//
-// createOfflineUserSession(realm, user1, "123", "something1");
-// createOfflineClientSession(realm, user1, "456", "123", fooClient.getId(), "something2");
-// createOfflineClientSession(realm, user1, "789", "123", barClient.getId(), "something3");
-//
-// createOfflineUserSession(realm, user2, "2123", "something4");
-// createOfflineClientSession(realm, user2, "2456", "2123", fooClient.getId(), "something5");
-//
-// commit();
-//
-// // Searching by clients
-// Assert.assertEquals(2, session.users().getOfflineSessionsCount(realm, fooClient));
-// Assert.assertEquals(1, session.users().getOfflineSessionsCount(realm, barClient));
-//
-// Collection<PersistentClientSessionModel> clientSessions = session.users().getOfflineClientSessions(realm, fooClient, 0, 10);
-// Assert.assertEquals(2, clientSessions.size());
-// clientSessions = session.users().getOfflineClientSessions(realm, fooClient, 0, 1);
-// PersistentClientSessionModel cls = clientSessions.iterator().next();
-// assertSessionEquals(cls, "456", "123", fooClient.getId(), user1.getId(), "something2");
-// clientSessions = session.users().getOfflineClientSessions(realm, fooClient, 1, 1);
-// cls = clientSessions.iterator().next();
-// assertSessionEquals(cls, "2456", "2123", fooClient.getId(), user2.getId(), "something5");
-//
-// clientSessions = session.users().getOfflineClientSessions(realm, barClient, 0, 10);
-// Assert.assertEquals(1, clientSessions.size());
-// cls = clientSessions.iterator().next();
-// assertSessionEquals(cls, "789", "123", barClient.getId(), user1.getId(), "something3");
-//
-// realm = realmManager.getRealmByName("original");
-// realm.removeClient(barClient.getId());
-//
-// commit();
-//
-// realm = realmManager.getRealmByName("original");
-// user1 = session.users().getUserByUsername("user1", realm);
-// Assert.assertEquals("something1", session.users().getOfflineUserSession(realm, user1, "123").getData());
-// Assert.assertEquals("something2", session.users().getOfflineClientSession(realm, user1, "456").getData());
-// Assert.assertNull(session.users().getOfflineClientSession(realm, user1, "789"));
-//
-// realm.removeClient(fooClient.getId());
-//
-// commit();
-//
-// realm = realmManager.getRealmByName("original");
-// user1 = session.users().getUserByUsername("user1", realm);
-// Assert.assertNull(session.users().getOfflineClientSession(realm, user1, "456"));
-// Assert.assertNull(session.users().getOfflineClientSession(realm, user1, "789"));
-// Assert.assertNull(session.users().getOfflineUserSession(realm, user1, "123"));
-// Assert.assertEquals(0, session.users().getOfflineUserSessions(realm, user1).size());
-// Assert.assertEquals(0, session.users().getOfflineClientSessions(realm, user1).size());
-// }
-//
-// private void createOfflineUserSession(RealmModel realm, UserModel user, String userSessionId, String data) {
-// PersistentUserSessionModel model = new PersistentUserSessionModel();
-// model.setUserSessionId(userSessionId);
-// model.setData(data);
-// session.users().createOfflineUserSession(realm, user, model);
-// }
-//
-// private void createOfflineClientSession(RealmModel realm, UserModel user, String clientSessionId, String userSessionId, String clientId, String data) {
-// PersistentClientSessionModel model = new PersistentClientSessionModel();
-// model.setClientSessionId(clientSessionId);
-// model.setUserSessionId(userSessionId);
-// model.setUserId(user.getId());
-// model.setClientId(clientId);
-// model.setData(data);
-// session.users().createOfflineClientSession(realm, model);
-// }
-
public static void assertEquals(UserModel expected, UserModel actual) {
Assert.assertEquals(expected.getUsername(), actual.getUsername());
Assert.assertEquals(expected.getCreatedTimestamp(), actual.getCreatedTimestamp());
@@ -377,14 +297,5 @@ public class UserModelTest extends AbstractModelTest {
Assert.assertArrayEquals(expectedRequiredActions, actualRequiredActions);
}
- private static void assertSessionEquals(PersistentClientSessionModel cls, String expectedClientSessionId, String expectedUserSessionId,
- String expectedClientId, String expectedUserId, String expectedData) {
- Assert.assertEquals(cls.getData(), expectedData);
- Assert.assertEquals(cls.getClientSessionId(), expectedClientSessionId);
- Assert.assertEquals(cls.getUserSessionId(), expectedUserSessionId);
- Assert.assertEquals(cls.getUserId(), expectedUserId);
- Assert.assertEquals(cls.getClientId(), expectedClientId);
- }
-
}
diff --git a/testsuite/integration/src/test/resources/model/testrealm.json b/testsuite/integration/src/test/resources/model/testrealm.json
index 53e7f7e..68ec4d3 100755
--- a/testsuite/integration/src/test/resources/model/testrealm.json
+++ b/testsuite/integration/src/test/resources/model/testrealm.json
@@ -120,19 +120,6 @@
"openid-connect": [ "gss delegation credential" ]
}
}
- ],
- "offlineUserSessions": [
- {
- "userSessionId": "123",
- "data": "something1",
- "offlineClientSessions": [
- {
- "clientSessionId": "456",
- "client": "OtherApp",
- "data": "something2"
- }
- ]
- }
]
},
{