Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,9 @@ protected SessionContext createSessionContext(SubjectContext subjectContext) {
if (host != null) {
sessionContext.setHost(host);
}
if (isVersioned()) {
sessionContext.setVersioned(true);
}
return sessionContext;
}

Expand Down Expand Up @@ -599,6 +602,11 @@ public void logout(Subject subject) {
}
}

@Override
public boolean isVersioned() {
return getSessionManager().isVersioned();
}

protected void stopSession(Subject subject) {
Session s = subject.getSession(false);
if (s != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,4 +310,15 @@ public void checkValid(SessionKey key) throws InvalidSessionException {

protected void onChange(Session s) {
}

@Override
public long incrementVersion(SessionKey key) {
Session session = lookupRequiredSession(key);
long version = 0;
if (session instanceof VersionedSession versionedSession && versionedSession.isVersioned()) {
version = versionedSession.incrementVersion();
onChange(session);
}
return version;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@
* @since 1.0
*/
public class DefaultSessionContext extends MapContext implements SessionContext {

@Serial
private static final long serialVersionUID = -1424160751361252966L;

private static final String HOST = DefaultSessionContext.class.getName() + ".HOST";
private static final String SESSION_ID = DefaultSessionContext.class.getName() + ".SESSION_ID";
private static final String VERSIONED_SESSION = DefaultSessionContext.class.getName() + ".VERSIONED_SESSION";

public DefaultSessionContext() {
super();
Expand All @@ -47,21 +47,36 @@ public DefaultSessionContext(Map<String, Object> map) {
super(map);
}

@Override
public String getHost() {
return getTypedValue(HOST, String.class);
}

@Override
public void setHost(String host) {
if (StringUtils.hasText(host)) {
put(HOST, host);
}
}

@Override
public Serializable getSessionId() {
return getTypedValue(SESSION_ID, Serializable.class);
}

@Override
public void setSessionId(Serializable sessionId) {
nullSafePut(SESSION_ID, sessionId);
}

@Override
public boolean isVersioned() {
var versioned = getTypedValue(VERSIONED_SESSION, Boolean.class);
return versioned != null && versioned;
}

@Override
public void setVersioned(boolean versioned) {
put(VERSIONED_SESSION, versioned);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.apache.shiro.cache.CacheManagerAware;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.CachingSessionDAO;
import org.apache.shiro.session.mgt.eis.MemorySessionDAO;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.slf4j.Logger;
Expand Down Expand Up @@ -245,4 +246,8 @@ protected Collection<Session> getActiveSessions() {
return active != null ? active : Collections.<Session>emptySet();
}

@Override
public boolean isVersioned() {
return sessionDAO instanceof CachingSessionDAO;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,21 @@ public interface NativeSessionManager extends SessionManager {
*/
Object removeAttribute(SessionKey sessionKey, Object attributeKey) throws InvalidSessionException;

Comment thread
lprimak marked this conversation as resolved.
/**
* Increments the version of the associated session for implementations that track session versions to
* enforce consistency across concurrent updates.
* <p>
* This method should be invoked once for each session mutation that must advance the session version,
* not once per request unless every request performs such a mutation.
* <p>
* Calling this method updates the version as managed by the implementation, but it does not by itself
* guarantee any persistence behavior beyond the implementation's normal session persistence semantics.
*
* @param sessionKey the session key to use to look up the target session.
* @return the session version after the increment has been applied. If session versioning is disabled,
* implementations should perform no version change and return the current effective version,
* typically {@code 0}.
* @throws InvalidSessionException if the specified session has stopped or expired prior to calling this method.
*/
long incrementVersion(SessionKey sessionKey) throws InvalidSessionException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,6 @@ public interface SessionContext extends Map<String, Object> {

void setSessionId(Serializable sessionId);

boolean isVersioned();
void setVersioned(boolean versioned);
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,20 @@ public interface SessionManager {
* @since 1.0
*/
Session getSession(SessionKey key) throws SessionException;

Comment thread
lprimak marked this conversation as resolved.
/**
* Returns {@code true} if sessions managed by this instance are versioned.
* <p/>
* In this context, &quot;versioned&quot; means that the underlying session implementation maintains a version
* value for a session and updates that value as session state changes, typically to support persistence
* and/or concurrency control in a backing store. This flag does not control whether sessions can be
* created, how they are looked up, cache ordering semantics, or general session lifecycle behavior.
* <p/>
* Implementations that do not maintain session version metadata should return {@code false}. Implementations
* that track and expose such version state should return {@code true}.
*
* @return {@code true} if managed sessions maintain version state, {@code false} otherwise.
* @since 3.0
*/
boolean isVersioned();
}
Loading
Loading