keycloak-aplcache
Changes
model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/ClientSessionEntity.java 2(+2 -0)
model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/SessionEntity.java 17(+17 -0)
model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProvider.java 16(+16 -0)
model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/ClientSessionAdapter.java 4(+4 -0)
model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/ClientSessionEntity.java 17(+17 -0)
model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProvider.java 8(+8 -0)
model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/ClientSessionAdapter.java 4(+3 -1)
model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/entities/ClientSessionEntity.java 17(+17 -0)
model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/MemUserSessionProvider.java 11(+11 -0)
Details
diff --git a/model/api/src/main/java/org/keycloak/models/UserSessionProvider.java b/model/api/src/main/java/org/keycloak/models/UserSessionProvider.java
index 3a64206..89f8cee 100755
--- a/model/api/src/main/java/org/keycloak/models/UserSessionProvider.java
+++ b/model/api/src/main/java/org/keycloak/models/UserSessionProvider.java
@@ -29,6 +29,7 @@ public interface UserSessionProvider extends Provider {
void removeUserSessions(RealmModel realm, UserModel user);
void removeExpiredUserSessions(RealmModel realm);
void removeUserSessions(RealmModel realm);
+ void removeClientSession(RealmModel realm, ClientSessionModel clientSession);
UsernameLoginFailureModel getUserLoginFailure(RealmModel realm, String username);
UsernameLoginFailureModel addUserLoginFailure(RealmModel realm, String username);
diff --git a/model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/ClientSessionEntity.java b/model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/ClientSessionEntity.java
index 3cb6614..a00e805 100755
--- a/model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/ClientSessionEntity.java
+++ b/model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/ClientSessionEntity.java
@@ -135,4 +135,6 @@ public class ClientSessionEntity extends SessionEntity {
public void setUserSessionNotes(Map<String, String> userSessionNotes) {
this.userSessionNotes = userSessionNotes;
}
+
+
}
diff --git a/model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/SessionEntity.java b/model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/SessionEntity.java
old mode 100644
new mode 100755
index 5d6fc3c..62e1861
--- a/model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/SessionEntity.java
+++ b/model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/SessionEntity.java
@@ -26,4 +26,21 @@ public class SessionEntity implements Serializable {
public void setRealm(String realm) {
this.realm = realm;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof SessionEntity)) return false;
+
+ SessionEntity that = (SessionEntity) o;
+
+ if (id != null ? !id.equals(that.id) : that.id != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return id != null ? id.hashCode() : 0;
+ }
}
diff --git a/model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProvider.java b/model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProvider.java
index e7ff079..2275a98 100755
--- a/model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProvider.java
+++ b/model/sessions-infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProvider.java
@@ -334,6 +334,21 @@ public class InfinispanUserSessionProvider implements UserSessionProvider {
}
}
+ @Override
+ public void removeClientSession(RealmModel realm, ClientSessionModel clientSession) {
+ UserSessionModel userSession = clientSession.getUserSession();
+ if (userSession != null) {
+ UserSessionEntity entity = ((UserSessionAdapter) userSession).getEntity();
+ if (entity.getClientSessions() != null) {
+ entity.getClientSessions().remove(clientSession.getId());
+
+ }
+ tx.replace(sessionCache, entity.getId(), entity);
+ }
+ tx.remove(sessionCache, clientSession.getId());
+ }
+
+
void dettachSession(UserSessionModel userSession, ClientSessionModel clientSession) {
UserSessionEntity entity = ((UserSessionAdapter) userSession).getEntity();
String clientSessionId = clientSession.getId();
@@ -359,6 +374,7 @@ public class InfinispanUserSessionProvider implements UserSessionProvider {
}
}
+
InfinispanKeycloakTransaction getTx() {
return tx;
}
diff --git a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/ClientSessionAdapter.java b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/ClientSessionAdapter.java
index e8498e9..a6b3016 100755
--- a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/ClientSessionAdapter.java
+++ b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/ClientSessionAdapter.java
@@ -128,6 +128,10 @@ public class ClientSessionAdapter implements ClientSessionModel {
return realm.getClientById(entity.getClientId());
}
+ public ClientSessionEntity getEntity() {
+ return entity;
+ }
+
@Override
public void setUserSession(UserSessionModel userSession) {
if (userSession == null) {
diff --git a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/ClientSessionEntity.java b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/ClientSessionEntity.java
index 300c45a..5789ea8 100755
--- a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/ClientSessionEntity.java
+++ b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/entities/ClientSessionEntity.java
@@ -186,4 +186,21 @@ public class ClientSessionEntity {
public void setUserSessionNotes(Collection<ClientUserSessionNoteEntity> userSessionNotes) {
this.userSessionNotes = userSessionNotes;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof ClientSessionEntity)) return false;
+
+ ClientSessionEntity that = (ClientSessionEntity) o;
+
+ if (id != null ? !id.equals(that.id) : that.id != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return id != null ? id.hashCode() : 0;
+ }
}
diff --git a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProvider.java b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProvider.java
index 23086d9..8614ec0 100755
--- a/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProvider.java
+++ b/model/sessions-jpa/src/main/java/org/keycloak/models/sessions/jpa/JpaUserSessionProvider.java
@@ -18,6 +18,7 @@ import org.keycloak.util.Time;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
+import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
@@ -48,6 +49,13 @@ public class JpaUserSessionProvider implements UserSessionProvider {
}
@Override
+ public void removeClientSession(RealmModel realm, ClientSessionModel clientSession) {
+ ClientSessionEntity clientSessionEntity = ((ClientSessionAdapter)clientSession).getEntity();
+ em.remove(clientSessionEntity);
+ em.flush();
+ }
+
+ @Override
public ClientSessionModel getClientSession(RealmModel realm, String id) {
ClientSessionEntity clientSession = em.find(ClientSessionEntity.class, id);
if (clientSession != null && clientSession.getRealmId().equals(realm.getId())) {
diff --git a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/ClientSessionAdapter.java b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/ClientSessionAdapter.java
index f9e52d0..3053a9d 100755
--- a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/ClientSessionAdapter.java
+++ b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/ClientSessionAdapter.java
@@ -39,7 +39,9 @@ public class ClientSessionAdapter implements ClientSessionModel {
return session.realms().getRealm(entity.getRealmId());
}
-
+ public ClientSessionEntity getEntity() {
+ return entity;
+ }
@Override
public ClientModel getClient() {
diff --git a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/entities/ClientSessionEntity.java b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/entities/ClientSessionEntity.java
index da5e050..7c6fb22 100755
--- a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/entities/ClientSessionEntity.java
+++ b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/entities/ClientSessionEntity.java
@@ -132,4 +132,21 @@ public class ClientSessionEntity {
public Map<String, String> getUserSessionNotes() {
return userSessionNotes;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof ClientSessionEntity)) return false;
+
+ ClientSessionEntity that = (ClientSessionEntity) o;
+
+ if (id != null ? !id.equals(that.id) : that.id != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return id != null ? id.hashCode() : 0;
+ }
}
diff --git a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/MemUserSessionProvider.java b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/MemUserSessionProvider.java
index 67a2180..ac6655f 100755
--- a/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/MemUserSessionProvider.java
+++ b/model/sessions-mem/src/main/java/org/keycloak/models/sessions/mem/MemUserSessionProvider.java
@@ -59,6 +59,17 @@ public class MemUserSessionProvider implements UserSessionProvider {
}
@Override
+ public void removeClientSession(RealmModel realm, ClientSessionModel clientSession) {
+ ClientSessionEntity entity = ((ClientSessionAdapter)clientSession).getEntity();
+ UserSessionModel userSession = clientSession.getUserSession();
+ if (userSession != null) {
+ UserSessionEntity userSessionEntity = ((UserSessionAdapter)userSession).getEntity();
+ userSessionEntity.getClientSessions().remove(entity);
+ }
+ clientSessions.remove(clientSession.getId());
+ }
+
+ @Override
public ClientSessionModel getClientSession(RealmModel realm, String id) {
ClientSessionEntity entity = clientSessions.get(id);
return entity != null ? new ClientSessionAdapter(session, this, realm, entity) : null;
diff --git a/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/MongoUserSessionProvider.java b/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/MongoUserSessionProvider.java
index 848fdeb..82045fd 100755
--- a/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/MongoUserSessionProvider.java
+++ b/model/sessions-mongo/src/main/java/org/keycloak/models/sessions/mongo/MongoUserSessionProvider.java
@@ -56,6 +56,19 @@ public class MongoUserSessionProvider implements UserSessionProvider {
}
@Override
+ public void removeClientSession(RealmModel realm, ClientSessionModel clientSession) {
+ MongoClientSessionEntity entity = ((ClientSessionAdapter)clientSession).getMongoEntity();
+ if (entity.getSessionId() != null) {
+ MongoUserSessionEntity userSessionEntity = getUserSessionEntity(realm, entity.getSessionId());
+ getMongoStore().pullItemFromList(userSessionEntity, "clientSessions", entity.getSessionId(), invocationContext);
+
+ }
+
+ mongoStore.removeEntity(entity, invocationContext);
+
+ }
+
+ @Override
public ClientSessionModel getClientSession(RealmModel realm, String id) {
MongoClientSessionEntity entity = getClientSessionEntity(id);
if (entity == null) return null;
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java
index 9db48d1..d5630bd 100755
--- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java
@@ -134,12 +134,9 @@ public class SamlProtocol implements LoginProtocol {
@Override
public Response cancelLogin(ClientSessionModel clientSession) {
- return getErrorResponse(clientSession, JBossSAMLURIConstants.STATUS_REQUEST_DENIED.get());
- }
-
- @Override
- public Response invalidSessionError(ClientSessionModel clientSession) {
- return getErrorResponse(clientSession, JBossSAMLURIConstants.STATUS_AUTHNFAILED.get());
+ Response error = getErrorResponse(clientSession, JBossSAMLURIConstants.STATUS_REQUEST_DENIED.get());
+ session.sessions().removeClientSession(realm, clientSession);
+ return error;
}
protected String getResponseIssuer(RealmModel realm) {
diff --git a/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java b/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java
index fce95a2..aa0a0cf 100755
--- a/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java
+++ b/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java
@@ -459,7 +459,8 @@ public class AuthenticationProcessor {
return authenticationComplete();
}
- protected void resetFlow() {
+ public static void resetFlow(ClientSessionModel clientSession) {
+ clientSession.setAuthenticatedUser(null);
clientSession.clearExecutionStatus();
clientSession.clearUserSessionNotes();
clientSession.removeNote(CURRENT_AUTHENTICATION_EXECUTION);
@@ -471,14 +472,14 @@ public class AuthenticationProcessor {
if (!execution.equals(current)) {
logger.debug("Current execution does not equal executed execution. Might be a page refresh");
logFailure();
- resetFlow();
+ resetFlow(clientSession);
return authenticate();
}
AuthenticationExecutionModel model = realm.getAuthenticationExecutionById(execution);
if (model == null) {
logger.debug("Cannot find execution, reseting flow");
logFailure();
- resetFlow();
+ resetFlow(clientSession);
return authenticate();
}
event.event(EventType.LOGIN);
diff --git a/services/src/main/java/org/keycloak/protocol/LoginProtocol.java b/services/src/main/java/org/keycloak/protocol/LoginProtocol.java
index be1711b..51676f3 100755
--- a/services/src/main/java/org/keycloak/protocol/LoginProtocol.java
+++ b/services/src/main/java/org/keycloak/protocol/LoginProtocol.java
@@ -28,7 +28,6 @@ public interface LoginProtocol extends Provider {
LoginProtocol setEventBuilder(EventBuilder event);
Response cancelLogin(ClientSessionModel clientSession);
- Response invalidSessionError(ClientSessionModel clientSession);
Response authenticated(UserSessionModel userSession, ClientSessionCode accessCode);
Response consentDenied(ClientSessionModel clientSession);
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
index 4ef8544..c002335 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
@@ -122,6 +122,7 @@ public class OIDCLoginProtocol implements LoginProtocol {
if (state != null) {
redirectUri.queryParam(OAuth2Constants.STATE, state);
}
+ session.sessions().removeClientSession(realm, clientSession);
return Response.status(302).location(redirectUri.build()).build();
}
diff --git a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
index cca6bb0..d921cf1 100755
--- a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
+++ b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
@@ -182,7 +182,15 @@ public class LoginActionsService {
} else if (!(clientCode.isActionActive(requiredAction) || clientCode.isActionActive(alternativeRequiredAction))) {
event.client(clientCode.getClientSession().getClient());
event.error(Errors.EXPIRED_CODE);
- response = ErrorPage.error(session, Messages.EXPIRED_CODE);
+ if (clientCode.getClientSession().getAction().equals(ClientSessionModel.Action.AUTHENTICATE.name())) {
+ AuthenticationProcessor.resetFlow(clientCode.getClientSession());
+ response = processAuthentication(null, clientCode.getClientSession());
+ } else {
+ if (clientCode.getClientSession().getUserSession() == null) {
+ session.sessions().removeClientSession(realm, clientCode.getClientSession());
+ }
+ response = ErrorPage.error(session, Messages.EXPIRED_CODE);
+ }
return false;
} else {
return true;
@@ -207,21 +215,26 @@ public class LoginActionsService {
return false;
}
ClientSessionModel clientSession = clientCode.getClientSession();
+ if (clientSession == null) {
+ event.error(Errors.INVALID_CODE);
+ response = ErrorPage.error(session, Messages.INVALID_CODE);
+ return false;
+ }
event.detail(Details.CODE_ID, clientSession.getId());
ClientModel client = clientSession.getClient();
if (client == null) {
event.error(Errors.CLIENT_NOT_FOUND);
response = ErrorPage.error(session, Messages.UNKNOWN_LOGIN_REQUESTER);
+ session.sessions().removeClientSession(realm, clientSession);
return false;
}
- session.getContext().setClient(client);
-
if (!client.isEnabled()) {
event.error(Errors.CLIENT_NOT_FOUND);
response = ErrorPage.error(session, Messages.LOGIN_REQUESTER_NOT_ENABLED);
+ session.sessions().removeClientSession(realm, clientSession);
return false;
}
- session.getContext().setClient(clientCode.getClientSession().getClient());
+ session.getContext().setClient(client);
return true;
}
}
@@ -239,7 +252,7 @@ public class LoginActionsService {
@QueryParam("execution") String execution) {
event.event(EventType.LOGIN);
Checks checks = new Checks();
- if (!checks.check(code)) {
+ if (!checks.check(code, ClientSessionModel.Action.AUTHENTICATE.name(), ClientSessionModel.Action.RECOVER_PASSWORD.name())) {
return checks.response;
}
event.detail(Details.CODE_ID, code);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java
index 17ca887..e3926ef 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java
@@ -137,6 +137,7 @@ public class ResetPasswordTest {
events.expectRequiredAction(EventType.SEND_RESET_PASSWORD).user(userId).detail(Details.USERNAME, "login-test").detail(Details.EMAIL, "login@test.com").assertEvent().getSessionId();
+ String src = driver.getPageSource();
resetPasswordPage.backToLogin();
assertTrue(loginPage.isCurrent());