Skip to content

Commit

Permalink
WFLY-4475 Replicate AuthenticatedSession when using custom authentica…
Browse files Browse the repository at this point in the history
…tion mechanisms
  • Loading branch information
pferraro committed Mar 31, 2015
1 parent 88c502f commit 46b428f
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 32 deletions.
Expand Up @@ -22,7 +22,6 @@
package org.wildfly.clustering.web.undertow.session;

import io.undertow.security.api.AuthenticatedSessionManager.AuthenticatedSession;
import io.undertow.security.idm.Account;
import io.undertow.server.HttpServerExchange;
import io.undertow.server.session.SessionConfig;
import io.undertow.server.session.SessionListener.SessionDestroyedReason;
Expand All @@ -31,6 +30,8 @@
import java.io.NotSerializableException;
import java.io.Serializable;
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
Expand All @@ -49,6 +50,8 @@
public class DistributableSession implements io.undertow.server.session.Session {
// Undertow stores the authenticated session in the HttpSession using a special attribute with the following name
private static final String AUTHENTICATED_SESSION_ATTRIBUTE_NAME = CachedAuthenticatedSessionHandler.class.getName() + ".AuthenticatedSession";
// These mechanisms can auto-reauthenticate and thus use local context (instead of replicating)
private static final Set<String> AUTO_REAUTHENTICATING_MECHANISMS = new HashSet<>(Arrays.asList(HttpServletRequest.BASIC_AUTH, HttpServletRequest.DIGEST_AUTH, HttpServletRequest.CLIENT_CERT_AUTH));

private final UndertowSessionManager manager;
private final Batch batch;
Expand Down Expand Up @@ -122,8 +125,8 @@ public Object getAttribute(String name) {
Session<LocalSessionContext> session = this.entry.getKey();
try (BatchContext context = this.manager.getSessionManager().getBatcher().resumeBatch(this.batch)) {
if (AUTHENTICATED_SESSION_ATTRIBUTE_NAME.equals(name)) {
Account account = (Account) session.getAttributes().getAttribute(name);
return (account != null) ? new AuthenticatedSession(account, HttpServletRequest.FORM_AUTH) : session.getLocalContext().getAuthenticatedSession();
AuthenticatedSession auth = (AuthenticatedSession) session.getAttributes().getAttribute(name);
return (auth != null) ? auth : session.getLocalContext().getAuthenticatedSession();
}
return session.getAttributes().getAttribute(name);
}
Expand All @@ -137,17 +140,8 @@ public Object setAttribute(String name, Object value) {
Session<LocalSessionContext> session = this.entry.getKey();
try (BatchContext context = this.manager.getSessionManager().getBatcher().resumeBatch(this.batch)) {
if (AUTHENTICATED_SESSION_ATTRIBUTE_NAME.equals(name)) {
AuthenticatedSession authSession = (AuthenticatedSession) value;
// If using FORM authentication, we store the corresponding Account in a session attribute
if (authSession.getMechanism().equals(HttpServletRequest.FORM_AUTH)) {
Account account = (Account) session.getAttributes().setAttribute(name, authSession.getAccount());
return (account != null) ? new AuthenticatedSession(account, HttpServletRequest.FORM_AUTH) : null;
}
// Otherwise we store the whole AuthenticatedSession in the local context
LocalSessionContext localContext = session.getLocalContext();
AuthenticatedSession old = localContext.getAuthenticatedSession();
localContext.setAuthenticatedSession(authSession);
return old;
AuthenticatedSession auth = (AuthenticatedSession) value;
return AUTO_REAUTHENTICATING_MECHANISMS.contains(auth.getMechanism()) ? this.setLocalContext(auth) : session.getAttributes().setAttribute(name, auth);
}
if (!(value instanceof Serializable)) {
throw new IllegalArgumentException(new NotSerializableException(value.getClass().getName()));
Expand All @@ -167,14 +161,8 @@ public Object removeAttribute(String name) {
Session<LocalSessionContext> session = this.entry.getKey();
try (BatchContext context = this.manager.getSessionManager().getBatcher().resumeBatch(this.batch)) {
if (AUTHENTICATED_SESSION_ATTRIBUTE_NAME.equals(name)) {
Account account = (Account) session.getAttributes().removeAttribute(name);
if (account != null) {
return new AuthenticatedSession(account, HttpServletRequest.FORM_AUTH);
}
LocalSessionContext localContext = session.getLocalContext();
AuthenticatedSession old = localContext.getAuthenticatedSession();
localContext.setAuthenticatedSession(null);
return old;
AuthenticatedSession auth = (AuthenticatedSession) session.getAttributes().removeAttribute(name);
return (auth != null) ? auth : this.setLocalContext(null);
}
Object old = session.getAttributes().removeAttribute(name);
if (old != null) {
Expand Down Expand Up @@ -218,4 +206,11 @@ public String changeSessionId(HttpServerExchange exchange, SessionConfig config)
return id;
}
}

private AuthenticatedSession setLocalContext(AuthenticatedSession auth) {
LocalSessionContext localContext = this.entry.getKey().getLocalContext();
AuthenticatedSession old = localContext.getAuthenticatedSession();
localContext.setAuthenticatedSession(auth);
return old;
}
}
Expand Up @@ -233,12 +233,13 @@ public void getAuthenticatedSessionAttribute() {
String name = CachedAuthenticatedSessionHandler.class.getName() + ".AuthenticatedSession";
SessionAttributes attributes = mock(SessionAttributes.class);
Account account = mock(Account.class);

AuthenticatedSession auth = new AuthenticatedSession(account, HttpServletRequest.FORM_AUTH);

when(this.manager.getSessionManager()).thenReturn(manager);
when(manager.getBatcher()).thenReturn(batcher);
when(batcher.resumeBatch(this.batch)).thenReturn(context);
when(this.session.getAttributes()).thenReturn(attributes);
when(attributes.getAttribute(name)).thenReturn(account);
when(attributes.getAttribute(name)).thenReturn(auth);

AuthenticatedSession result = (AuthenticatedSession) this.adapter.getAttribute(name);

Expand Down Expand Up @@ -392,16 +393,17 @@ public void setAuthenticatedSessionAttribute() {
String name = CachedAuthenticatedSessionHandler.class.getName() + ".AuthenticatedSession";
SessionAttributes attributes = mock(SessionAttributes.class);
Account account = mock(Account.class);
AuthenticatedSession session = new AuthenticatedSession(account, HttpServletRequest.FORM_AUTH);
AuthenticatedSession auth = new AuthenticatedSession(account, HttpServletRequest.FORM_AUTH);
Account oldAccount = mock(Account.class);
AuthenticatedSession oldAuth = new AuthenticatedSession(oldAccount, HttpServletRequest.FORM_AUTH);

when(this.manager.getSessionManager()).thenReturn(manager);
when(manager.getBatcher()).thenReturn(batcher);
when(batcher.resumeBatch(this.batch)).thenReturn(context);
when(this.session.getAttributes()).thenReturn(attributes);
when(attributes.setAttribute(name, account)).thenReturn(oldAccount);
when(attributes.setAttribute(name, auth)).thenReturn(oldAuth);

AuthenticatedSession result = (AuthenticatedSession) this.adapter.setAttribute(name, session);
AuthenticatedSession result = (AuthenticatedSession) this.adapter.setAttribute(name, auth);

assertSame(oldAccount, result.getAccount());
assertSame(HttpServletRequest.FORM_AUTH, result.getMechanism());
Expand All @@ -410,27 +412,27 @@ public void setAuthenticatedSessionAttribute() {

reset(context);

when(attributes.setAttribute(name, account)).thenReturn(null);
when(attributes.setAttribute(name, auth)).thenReturn(null);

result = (AuthenticatedSession) this.adapter.setAttribute(name, session);
result = (AuthenticatedSession) this.adapter.setAttribute(name, auth);

assertNull(result);

verify(context).close();

reset(context);

session = new AuthenticatedSession(account, HttpServletRequest.BASIC_AUTH);
auth = new AuthenticatedSession(account, HttpServletRequest.BASIC_AUTH);
AuthenticatedSession oldSession = new AuthenticatedSession(oldAccount, HttpServletRequest.BASIC_AUTH);

LocalSessionContext localContext = mock(LocalSessionContext.class);

when(this.session.getLocalContext()).thenReturn(localContext);
when(localContext.getAuthenticatedSession()).thenReturn(oldSession);

result = (AuthenticatedSession) this.adapter.setAttribute(name, session);
result = (AuthenticatedSession) this.adapter.setAttribute(name, auth);

verify(localContext).setAuthenticatedSession(same(session));
verify(localContext).setAuthenticatedSession(same(auth));
verify(context).close();
}

Expand Down

0 comments on commit 46b428f

Please sign in to comment.