SAML IdMapperUpdaterSessionListener should be added always and must implement HttpSessionIdListener interface
Closes #32084 Signed-off-by: rmartinc <rmartinc@redhat.com>
This commit is contained in:
parent
3ff825807f
commit
a38d3b2f55
4 changed files with 50 additions and 7 deletions
|
@ -24,6 +24,7 @@ import jakarta.servlet.http.HttpSession;
|
|||
import jakarta.servlet.http.HttpSessionAttributeListener;
|
||||
import jakarta.servlet.http.HttpSessionBindingEvent;
|
||||
import jakarta.servlet.http.HttpSessionEvent;
|
||||
import jakarta.servlet.http.HttpSessionIdListener;
|
||||
import jakarta.servlet.http.HttpSessionListener;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
|
@ -31,7 +32,7 @@ import org.jboss.logging.Logger;
|
|||
*
|
||||
* @author hmlnarik
|
||||
*/
|
||||
public class IdMapperUpdaterSessionListener implements HttpSessionListener, HttpSessionAttributeListener {
|
||||
public class IdMapperUpdaterSessionListener implements HttpSessionListener, HttpSessionAttributeListener, HttpSessionIdListener {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(IdMapperUpdaterSessionListener.class);
|
||||
|
||||
|
@ -56,6 +57,15 @@ public class IdMapperUpdaterSessionListener implements HttpSessionListener, Http
|
|||
unmap(session.getId(), session.getAttribute(SamlSession.class.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sessionIdChanged(HttpSessionEvent hse, String oldSessionId) {
|
||||
LOG.debugf("Session changed ID from %s", oldSessionId);
|
||||
HttpSession session = hse.getSession();
|
||||
Object value = session.getAttribute(SamlSession.class.getName());
|
||||
unmap(oldSessionId, value);
|
||||
map(session.getId(), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attributeAdded(HttpSessionBindingEvent hsbe) {
|
||||
HttpSession session = hsbe.getSession();
|
||||
|
|
|
@ -156,14 +156,14 @@ public class KeycloakConfigurationServletListener implements ServletContextListe
|
|||
public void addTokenStoreUpdaters(ServletContext servletContext) {
|
||||
SessionIdMapperUpdater updater = this.idMapperUpdater;
|
||||
|
||||
servletContext.addListener(new IdMapperUpdaterSessionListener(idMapper)); // This takes care of HTTP sessions manipulated locally
|
||||
|
||||
try {
|
||||
String idMapperSessionUpdaterClasses = servletContext.getInitParameter("keycloak.sessionIdMapperUpdater.classes");
|
||||
if (idMapperSessionUpdaterClasses == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
servletContext.addListener(new IdMapperUpdaterSessionListener(idMapper)); // This takes care of HTTP sessions manipulated locally
|
||||
|
||||
updater = SessionIdMapperUpdater.DIRECT;
|
||||
|
||||
for (String clazz : idMapperSessionUpdaterClasses.split("\\s*,\\s*")) {
|
||||
|
|
|
@ -23,7 +23,6 @@ import org.keycloak.adapters.saml.SamlAuthenticationError;
|
|||
import org.keycloak.adapters.saml.SamlPrincipal;
|
||||
import org.keycloak.adapters.saml.SamlSession;
|
||||
import org.keycloak.adapters.spi.AuthenticationError;
|
||||
import org.keycloak.saml.processing.core.saml.v2.constants.X500SAMLProfileConstants;
|
||||
|
||||
import jakarta.servlet.RequestDispatcher;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
@ -45,8 +44,6 @@ import java.util.Arrays;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.transform.OutputKeys;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
|
@ -104,11 +101,19 @@ public class SendUsernameServlet {
|
|||
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("change-session-id")
|
||||
public Response changeSessionId() throws IOException {
|
||||
System.out.println("In SendUsername Servlet changeSessionId()");
|
||||
final String sessionId = httpServletRequest.changeSessionId();
|
||||
|
||||
return Response.ok(sessionId).header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_TYPE + ";charset=UTF-8").build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("getAssertionFromDocument")
|
||||
public Response getAssertionFromDocument() throws IOException, TransformerException {
|
||||
sentPrincipal = httpServletRequest.getUserPrincipal();
|
||||
DocumentBuilderFactory domFact = DocumentBuilderFactory.newInstance();
|
||||
Document doc = ((SamlPrincipal) sentPrincipal).getAssertionDocument();
|
||||
String xml = "";
|
||||
if (doc != null) {
|
||||
|
|
|
@ -1987,6 +1987,34 @@ public class SAMLServletAdapterTest extends AbstractSAMLServletAdapterTest {
|
|||
checkLoggedOut(salesPostSigEmailServletPage, testRealmSAMLPostLoginPage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChangeSessionID() throws Exception {
|
||||
// login in the employeeDom application
|
||||
assertSuccessfulLogin(employeeDomServletPage, bburkeUser, testRealmSAMLPostLoginPage, "principal=bburke");
|
||||
assertSuccessfullyLoggedIn(employeeDomServletPage, "principal=bburke");
|
||||
String sessionId = driver.manage().getCookieNamed("JSESSIONID").getValue();
|
||||
|
||||
// retrieve the saml document
|
||||
driver.navigate().to(employeeDomServletPage.getUriBuilder().clone().path("getAssertionFromDocument").build().toURL());
|
||||
waitForPageToLoad();
|
||||
String xml = getRawPageSource();
|
||||
Assert.assertNotEquals("", xml);
|
||||
|
||||
// change the session id
|
||||
driver.navigate().to(employeeDomServletPage.getUriBuilder().clone().path("change-session-id").build().toURL());
|
||||
waitForPageToLoad();
|
||||
Assert.assertNotEquals("SessionID has not been changed at login", sessionId, driver.manage().getCookieNamed("JSESSIONID").getValue());
|
||||
|
||||
// retrieve again the saml document and should be the same as login should be maintained
|
||||
driver.navigate().to(employeeDomServletPage.getUriBuilder().clone().path("getAssertionFromDocument").build().toURL());
|
||||
waitForPageToLoad();
|
||||
Assert.assertEquals(xml, getRawPageSource());
|
||||
|
||||
// logout
|
||||
employeeDomServletPage.logout();
|
||||
checkLoggedOut(employeeDomServletPage, testRealmSAMLPostLoginPage);
|
||||
}
|
||||
|
||||
public static void printDocument(Source doc, OutputStream out) throws IOException, TransformerException {
|
||||
TransformerFactory tf = TransformerFactory.newInstance();
|
||||
Transformer transformer = tf.newTransformer();
|
||||
|
|
Loading…
Reference in a new issue