keycloak-aplcache
Changes
model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProviderFactory.java 1(+1 -0)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/AuthenticatedClientSessionEntity.java 3(+2 -1)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/TrustStoreEmailTest.java 57(+52 -5)
Details
diff --git a/distribution/demo-dist/src/main/xslt/standalone.xsl b/distribution/demo-dist/src/main/xslt/standalone.xsl
index 882d1b1..7c0b3c1 100755
--- a/distribution/demo-dist/src/main/xslt/standalone.xsl
+++ b/distribution/demo-dist/src/main/xslt/standalone.xsl
@@ -89,6 +89,7 @@
<eviction max-entries="10000" strategy="LRU"/>
</local-cache>
<local-cache name="sessions"/>
+ <local-cache name="authenticationSessions"/>
<local-cache name="offlineSessions"/>
<local-cache name="loginFailures"/>
<local-cache name="authorization"/>
diff --git a/distribution/server-overlay/src/main/cli/keycloak-install-base.cli b/distribution/server-overlay/src/main/cli/keycloak-install-base.cli
index f24502a..b8a7e89 100644
--- a/distribution/server-overlay/src/main/cli/keycloak-install-base.cli
+++ b/distribution/server-overlay/src/main/cli/keycloak-install-base.cli
@@ -6,6 +6,7 @@ embed-server --server-config=standalone.xml
/subsystem=infinispan/cache-container=keycloak/local-cache=users:add()
/subsystem=infinispan/cache-container=keycloak/local-cache=users/eviction=EVICTION:add(max-entries=10000,strategy=LRU)
/subsystem=infinispan/cache-container=keycloak/local-cache=sessions:add()
+/subsystem=infinispan/cache-container=keycloak/local-cache=authenticationSessions:add()
/subsystem=infinispan/cache-container=keycloak/local-cache=offlineSessions:add()
/subsystem=infinispan/cache-container=keycloak/local-cache=loginFailures:add()
/subsystem=infinispan/cache-container=keycloak/local-cache=work:add()
diff --git a/distribution/server-overlay/src/main/cli/keycloak-install-ha-base.cli b/distribution/server-overlay/src/main/cli/keycloak-install-ha-base.cli
index ec2b56f..e092374 100644
--- a/distribution/server-overlay/src/main/cli/keycloak-install-ha-base.cli
+++ b/distribution/server-overlay/src/main/cli/keycloak-install-ha-base.cli
@@ -7,6 +7,7 @@ embed-server --server-config=standalone-ha.xml
/subsystem=infinispan/cache-container=keycloak/local-cache=users:add()
/subsystem=infinispan/cache-container=keycloak/local-cache=users/eviction=EVICTION:add(max-entries=10000,strategy=LRU)
/subsystem=infinispan/cache-container=keycloak/distributed-cache=sessions:add(mode="SYNC",owners="1")
+/subsystem=infinispan/cache-container=keycloak/distributed-cache=authenticationSessions:add(mode="SYNC",owners="1")
/subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineSessions:add(mode="SYNC",owners="1")
/subsystem=infinispan/cache-container=keycloak/distributed-cache=loginFailures:add(mode="SYNC",owners="1")
/subsystem=infinispan/cache-container=keycloak/local-cache=authorization:add()
diff --git a/model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProviderFactory.java b/model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProviderFactory.java
index 934f0e8..0f63129 100755
--- a/model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProviderFactory.java
+++ b/model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProviderFactory.java
@@ -118,6 +118,7 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
cacheManager.defineConfiguration(InfinispanConnectionProvider.USER_REVISIONS_CACHE_NAME, getRevisionCacheConfig(userRevisionsMaxEntries));
cacheManager.getCache(InfinispanConnectionProvider.USER_REVISIONS_CACHE_NAME, true);
cacheManager.getCache(InfinispanConnectionProvider.AUTHORIZATION_CACHE_NAME, true);
+ cacheManager.getCache(InfinispanConnectionProvider.AUTHENTICATION_SESSIONS_CACHE_NAME, true);
cacheManager.getCache(InfinispanConnectionProvider.KEYS_CACHE_NAME, true);
logger.debugv("Using container managed Infinispan cache container, lookup={1}", cacheContainerLookup);
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/AuthenticatedClientSessionEntity.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/AuthenticatedClientSessionEntity.java
index c7839f4..f892477 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/AuthenticatedClientSessionEntity.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/AuthenticatedClientSessionEntity.java
@@ -17,13 +17,14 @@
package org.keycloak.models.sessions.infinispan.entities;
+import java.io.Serializable;
import java.util.Map;
import java.util.Set;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
-public class AuthenticatedClientSessionEntity {
+public class AuthenticatedClientSessionEntity implements Serializable {
private String id;
private String authMethod;
diff --git a/services/src/main/java/org/keycloak/authentication/requiredactions/VerifyEmail.java b/services/src/main/java/org/keycloak/authentication/requiredactions/VerifyEmail.java
index ad84f9d..ae56970 100755
--- a/services/src/main/java/org/keycloak/authentication/requiredactions/VerifyEmail.java
+++ b/services/src/main/java/org/keycloak/authentication/requiredactions/VerifyEmail.java
@@ -27,6 +27,8 @@ import org.keycloak.common.util.Time;
import org.keycloak.email.EmailException;
import org.keycloak.email.EmailTemplateProvider;
import org.keycloak.events.Details;
+import org.keycloak.events.Errors;
+import org.keycloak.events.EventBuilder;
import org.keycloak.events.EventType;
import org.keycloak.forms.login.LoginFormsProvider;
import org.keycloak.models.*;
@@ -74,8 +76,8 @@ public class VerifyEmail implements RequiredActionProvider, RequiredActionFactor
// Do not allow resending e-mail by simple page refresh, i.e. when e-mail sent, it should be resent properly via email-verification endpoint
if (! Objects.equals(authSession.getAuthNote(Constants.VERIFY_EMAIL_KEY), email)) {
authSession.setAuthNote(Constants.VERIFY_EMAIL_KEY, email);
- context.getEvent().clone().event(EventType.SEND_VERIFY_EMAIL).detail(Details.EMAIL, email).success();
- challenge = sendVerifyEmail(context.getSession(), loginFormsProvider, context.getUser(), context.getAuthenticationSession());
+ EventBuilder event = context.getEvent().clone().event(EventType.SEND_VERIFY_EMAIL).detail(Details.EMAIL, email);
+ challenge = sendVerifyEmail(context.getSession(), loginFormsProvider, context.getUser(), context.getAuthenticationSession(), event);
} else {
challenge = loginFormsProvider.createResponse(UserModel.RequiredAction.VERIFY_EMAIL);
}
@@ -126,7 +128,7 @@ public class VerifyEmail implements RequiredActionProvider, RequiredActionFactor
return UserModel.RequiredAction.VERIFY_EMAIL.name();
}
- private Response sendVerifyEmail(KeycloakSession session, LoginFormsProvider forms, UserModel user, AuthenticationSessionModel authSession) throws UriBuilderException, IllegalArgumentException {
+ private Response sendVerifyEmail(KeycloakSession session, LoginFormsProvider forms, UserModel user, AuthenticationSessionModel authSession, EventBuilder event) throws UriBuilderException, IllegalArgumentException {
RealmModel realm = session.getContext().getRealm();
UriInfo uriInfo = session.getContext().getUri();
@@ -144,9 +146,10 @@ public class VerifyEmail implements RequiredActionProvider, RequiredActionFactor
try {
session.getProvider(EmailTemplateProvider.class).setRealm(realm).setUser(user).sendVerifyEmail(link, expirationInMinutes);
+ event.success();
} catch (EmailException e) {
logger.error("Failed to send verification email", e);
- return forms.createResponse(RequiredAction.VERIFY_EMAIL);
+ event.error(Errors.EMAIL_SEND_FAILED);
}
return forms.createResponse(UserModel.RequiredAction.VERIFY_EMAIL);
diff --git a/services/src/main/java/org/keycloak/authorization/admin/PolicyEvaluationService.java b/services/src/main/java/org/keycloak/authorization/admin/PolicyEvaluationService.java
index 82cbddf..24e1a89 100644
--- a/services/src/main/java/org/keycloak/authorization/admin/PolicyEvaluationService.java
+++ b/services/src/main/java/org/keycloak/authorization/admin/PolicyEvaluationService.java
@@ -237,6 +237,7 @@ public class PolicyEvaluationService {
AuthenticationSessionModel authSession = keycloakSession.authenticationSessions().createAuthenticationSession(id, realm, clientModel);
authSession.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
+ authSession.setAuthenticatedUser(userModel);
userSession = keycloakSession.sessions().createUserSession(id, realm, userModel, userModel.getUsername(), "127.0.0.1", "passwd", false, null, null);
AuthenticationManager.setRolesAndMappersInSession(authSession);
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/TrustStoreEmailTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/TrustStoreEmailTest.java
index 59d277c..7fb9692 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/TrustStoreEmailTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/TrustStoreEmailTest.java
@@ -18,17 +18,23 @@ package org.keycloak.testsuite.account;
import org.jboss.arquillian.graphene.page.Page;
import org.junit.After;
+import org.junit.Rule;
import org.junit.Test;
+import org.keycloak.events.Details;
+import org.keycloak.events.Errors;
+import org.keycloak.events.EventType;
+import org.keycloak.representations.idm.EventRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
+import org.keycloak.testsuite.Assert;
+import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.auth.page.AuthRealm;
import org.keycloak.testsuite.auth.page.account.AccountManagement;
import org.keycloak.testsuite.auth.page.login.OIDCLogin;
import org.keycloak.testsuite.auth.page.login.VerifyEmail;
import org.keycloak.testsuite.util.MailServerConfiguration;
-import org.keycloak.testsuite.util.RealmRepUtil;
import org.keycloak.testsuite.util.SslMailServer;
import static org.junit.Assert.assertEquals;
@@ -54,6 +60,9 @@ public class TrustStoreEmailTest extends AbstractTestRealmKeycloakTest {
@Page
private VerifyEmail testRealmVerifyEmailPage;
+ @Rule
+ public AssertEvents events = new AssertEvents(this);
+
@Override
public void configureTestRealm(RealmRepresentation testRealm) {
log.info("enable verify email and configure smtp server to run with ssl in test realm");
@@ -86,6 +95,15 @@ public class TrustStoreEmailTest extends AbstractTestRealmKeycloakTest {
accountManagement.navigateTo();
testRealmLoginPage.form().login(user.getUsername(), "password");
+ EventRepresentation sendEvent = events.expectRequiredAction(EventType.SEND_VERIFY_EMAIL)
+ .user(user.getId())
+ .client("account")
+ .detail(Details.USERNAME, "test-user@localhost")
+ .detail(Details.EMAIL, "test-user@localhost")
+ .removeDetail(Details.REDIRECT_URI)
+ .assertEvent();
+ String mailCodeId = sendEvent.getDetails().get(Details.CODE_ID);
+
assertEquals("You need to verify your email address to activate your account.",
testRealmVerifyEmailPage.getFeedbackText());
@@ -96,6 +114,23 @@ public class TrustStoreEmailTest extends AbstractTestRealmKeycloakTest {
driver.navigate().to(verifyEmailUrl);
+ events.expectRequiredAction(EventType.VERIFY_EMAIL)
+ .user(user.getId())
+ .client("account")
+ .detail(Details.USERNAME, "test-user@localhost")
+ .detail(Details.EMAIL, "test-user@localhost")
+ .detail(Details.CODE_ID, mailCodeId)
+ .removeDetail(Details.REDIRECT_URI)
+ .assertEvent();
+
+ events.expectLogin()
+ .client("account")
+ .user(user.getId())
+ .session(mailCodeId)
+ .detail(Details.USERNAME, "test-user@localhost")
+ .removeDetail(Details.REDIRECT_URI)
+ .assertEvent();
+
assertCurrentUrlStartsWith(accountManagement);
accountManagement.signOut();
testRealmLoginPage.form().login(user.getUsername(), "password");
@@ -103,15 +138,27 @@ public class TrustStoreEmailTest extends AbstractTestRealmKeycloakTest {
}
@Test
- public void verifyEmailWithSslWrongCertificate() {
+ public void verifyEmailWithSslWrongCertificate() throws Exception {
UserRepresentation user = ApiUtil.findUserByUsername(testRealm(), "test-user@localhost");
SslMailServer.startWithSsl(this.getClass().getClassLoader().getResource(SslMailServer.INVALID_KEY).getFile());
accountManagement.navigateTo();
loginPage.form().login(user.getUsername(), "password");
- assertEquals("Failed to send email, please try again later.\n" +
- "« Back to Application",
- testRealmVerifyEmailPage.getErrorMessage());
+ events.expectRequiredAction(EventType.SEND_VERIFY_EMAIL_ERROR)
+ .error(Errors.EMAIL_SEND_FAILED)
+ .user(user.getId())
+ .client("account")
+ .detail(Details.USERNAME, "test-user@localhost")
+ .detail(Details.EMAIL, "test-user@localhost")
+ .removeDetail(Details.REDIRECT_URI)
+ .assertEvent();
+
+ // Email wasn't send
+ Assert.assertNull(SslMailServer.getLastReceivedMessage());
+
+ // Email wasn't send, but we won't notify end user about that. Admin is aware due to the error in the logs and the SEND_VERIFY_EMAIL_ERROR event.
+ assertEquals("You need to verify your email address to activate your account.",
+ testRealmVerifyEmailPage.getFeedbackText());
}
}
\ No newline at end of file
diff --git a/wildfly/server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakServerDeploymentProcessor.java b/wildfly/server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakServerDeploymentProcessor.java
index 96078ff..8567376 100755
--- a/wildfly/server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakServerDeploymentProcessor.java
+++ b/wildfly/server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakServerDeploymentProcessor.java
@@ -41,7 +41,7 @@ import java.util.List;
public class KeycloakServerDeploymentProcessor implements DeploymentUnitProcessor {
private static final String[] CACHES = new String[] {
- "realms", "users","sessions","offlineSessions","loginFailures","work","authorization","keys"
+ "realms", "users","sessions","authenticationSessions","offlineSessions","loginFailures","work","authorization","keys"
};
// This param name is defined again in Keycloak Services class
diff --git a/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-infinispan.xml b/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-infinispan.xml
index 205c1f5..83f7654 100755
--- a/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-infinispan.xml
+++ b/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-infinispan.xml
@@ -32,6 +32,7 @@
<eviction max-entries="10000" strategy="LRU"/>
</local-cache>
<local-cache name="sessions"/>
+ <local-cache name="authenticationSessions"/>
<local-cache name="offlineSessions"/>
<local-cache name="loginFailures"/>
<local-cache name="work"/>
@@ -97,6 +98,7 @@
<eviction max-entries="10000" strategy="LRU"/>
</local-cache>
<distributed-cache name="sessions" mode="SYNC" owners="1"/>
+ <distributed-cache name="authenticationSessions" mode="SYNC" owners="1"/>
<distributed-cache name="offlineSessions" mode="SYNC" owners="1"/>
<distributed-cache name="loginFailures" mode="SYNC" owners="1"/>
<local-cache name="authorization">
diff --git a/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-infinispan2.xml b/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-infinispan2.xml
index 95bcffd..5e706dc 100755
--- a/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-infinispan2.xml
+++ b/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-infinispan2.xml
@@ -32,6 +32,7 @@
<eviction max-entries="10000" strategy="LRU"/>
</local-cache>
<local-cache name="sessions"/>
+ <local-cache name="authenticationSessions"/>
<local-cache name="offlineSessions"/>
<local-cache name="loginFailures"/>
<local-cache name="work"/>
@@ -100,6 +101,7 @@
<eviction max-entries="10000" strategy="LRU"/>
</local-cache>
<distributed-cache name="sessions" mode="SYNC" owners="1"/>
+ <distributed-cache name="authenticationSessions" mode="SYNC" owners="1"/>
<distributed-cache name="offlineSessions" mode="SYNC" owners="1"/>
<distributed-cache name="loginFailures" mode="SYNC" owners="1"/>
<local-cache name="authorization">