📄 portletsessioncontextintegrationinterceptor.java
字号:
private boolean preHandle(PortletRequest request, PortletResponse response,
Object handler) throws Exception {
PortletSession portletSession = null;
boolean portletSessionExistedAtStartOfRequest = false;
// see if the portlet session already exists (or should be eagerly created)
try {
portletSession = request.getPortletSession(forceEagerSessionCreation);
} catch (IllegalStateException ignored) {}
// if there is a session, then see if there is a context to bring in
if (portletSession != null) {
// remember that the session already existed
portletSessionExistedAtStartOfRequest = true;
// attempt to retrieve the context from the session
Object contextFromSessionObject = portletSession.getAttribute(ACEGI_SECURITY_CONTEXT_KEY, portletSessionScope());
// if we got a context then place it into the holder
if (contextFromSessionObject != null) {
// if we are supposed to clone it, then do so
if (cloneFromPortletSession) {
Assert.isInstanceOf(Cloneable.class, contextFromSessionObject,
"Context must implement Clonable and provide a Object.clone() method");
try {
Method m = contextFromSessionObject.getClass().getMethod("clone", new Class[] {});
if (!m.isAccessible()) {
m.setAccessible(true);
}
contextFromSessionObject = m.invoke(contextFromSessionObject, new Object[] {});
}
catch (Exception ex) {
ReflectionUtils.handleReflectionException(ex);
}
}
// if what we got is a valid context then place it into the holder, otherwise create a new one
if (contextFromSessionObject instanceof SecurityContext) {
if (logger.isDebugEnabled())
logger.debug("Obtained from ACEGI_SECURITY_CONTEXT a valid SecurityContext and "
+ "set to SecurityContextHolder: '" + contextFromSessionObject + "'");
SecurityContextHolder.setContext((SecurityContext) contextFromSessionObject);
} else {
if (logger.isWarnEnabled())
logger.warn("ACEGI_SECURITY_CONTEXT did not contain a SecurityContext but contained: '"
+ contextFromSessionObject
+ "'; are you improperly modifying the PortletSession directly "
+ "(you should always use SecurityContextHolder) or using the PortletSession attribute "
+ "reserved for this class? - new SecurityContext instance associated with "
+ "SecurityContextHolder");
SecurityContextHolder.setContext(generateNewContext());
}
} else {
// there was no context in the session, so create a new context and put it in the holder
if (logger.isDebugEnabled())
logger.debug("PortletSession returned null object for ACEGI_SECURITY_CONTEXT - new "
+ "SecurityContext instance associated with SecurityContextHolder");
SecurityContextHolder.setContext(generateNewContext());
}
} else {
// there was no session, so create a new context and place it in the holder
if (logger.isDebugEnabled())
logger.debug("No PortletSession currently exists - new SecurityContext instance "
+ "associated with SecurityContextHolder");
SecurityContextHolder.setContext(generateNewContext());
}
// place attributes onto the request to remember if the session existed and the hashcode of the context
request.setAttribute(SESSION_EXISTED, new Boolean(portletSessionExistedAtStartOfRequest));
request.setAttribute(CONTEXT_HASHCODE, new Integer(SecurityContextHolder.getContext().hashCode()));
return true;
}
private void afterCompletion(PortletRequest request, PortletResponse response,
Object handler, Exception ex) throws Exception {
PortletSession portletSession = null;
// retrieve the attributes that remember if the session existed and the hashcode of the context
boolean portletSessionExistedAtStartOfRequest = ((Boolean)request.getAttribute(SESSION_EXISTED)).booleanValue();
int oldContextHashCode = ((Integer)request.getAttribute(CONTEXT_HASHCODE)).intValue();
// try to retrieve an existing portlet session
try {
portletSession = request.getPortletSession(false);
} catch (IllegalStateException ignored) {}
// if there is now no session but there was one at the beginning then it must have been invalidated
if ((portletSession == null) && portletSessionExistedAtStartOfRequest) {
if (logger.isDebugEnabled())
logger.debug("PortletSession is now null, but was not null at start of request; "
+ "session was invalidated, so do not create a new session");
}
// create a new portlet session if we need to
if ((portletSession == null) && !portletSessionExistedAtStartOfRequest) {
// if we're not allowed to create a new session, then report that
if (!allowSessionCreation) {
if (logger.isDebugEnabled())
logger.debug("The PortletSession is currently null, and the "
+ "PortletSessionContextIntegrationInterceptor is prohibited from creating a PortletSession "
+ "(because the allowSessionCreation property is false) - SecurityContext thus not "
+ "stored for next request");
}
// if the context was changed during the request, then go ahead and create a session
else if (!contextObject.equals(SecurityContextHolder.getContext())) {
if (logger.isDebugEnabled())
logger.debug("PortletSession being created as SecurityContextHolder contents are non-default");
try {
portletSession = request.getPortletSession(true);
} catch (IllegalStateException ignored) {}
}
// if nothing in the context changed, then don't bother to create a session
else {
if (logger.isDebugEnabled())
logger.debug("PortletSession is null, but SecurityContextHolder has not changed from default: ' "
+ SecurityContextHolder.getContext()
+ "'; not creating PortletSession or storing SecurityContextHolder contents");
}
}
// if the session exists and the context has changes, then store the context back into the session
if ((portletSession != null)
&& (SecurityContextHolder.getContext().hashCode() != oldContextHashCode)) {
portletSession.setAttribute(ACEGI_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext(), portletSessionScope());
if (logger.isDebugEnabled())
logger.debug("SecurityContext stored to PortletSession: '"
+ SecurityContextHolder.getContext() + "'");
}
// remove the contents of the holder
SecurityContextHolder.clearContext();
if (logger.isDebugEnabled())
logger.debug("SecurityContextHolder set to new context, as request processing completed");
}
/**
* Creates a new <code>SecurityContext</code> object. The specific class is
* determined by the setting of the {@link #context} property.
* @return the new <code>SecurityContext</code>
* @throws PortletException if the creation throws an <code>InstantiationException</code> or
* an <code>IllegalAccessException</code>, then this method will wrap them in a
* <code>PortletException</code>
*/
public SecurityContext generateNewContext() throws PortletException {
try {
return (SecurityContext) this.context.newInstance();
} catch (InstantiationException ie) {
throw new PortletException(ie);
} catch (IllegalAccessException iae) {
throw new PortletException(iae);
}
}
private int portletSessionScope() {
// return the appropriate scope setting based on our property value
return (this.useApplicationScopePortletSession ?
PortletSession.APPLICATION_SCOPE : PortletSession.PORTLET_SCOPE);
}
public Class getContext() {
return context;
}
public void setContext(Class secureContext) {
this.context = secureContext;
}
public boolean isAllowSessionCreation() {
return allowSessionCreation;
}
public void setAllowSessionCreation(boolean allowSessionCreation) {
this.allowSessionCreation = allowSessionCreation;
}
public boolean isForceEagerSessionCreation() {
return forceEagerSessionCreation;
}
public void setForceEagerSessionCreation(boolean forceEagerSessionCreation) {
this.forceEagerSessionCreation = forceEagerSessionCreation;
}
public boolean isCloneFromPortletSession() {
return cloneFromPortletSession;
}
public void setCloneFromPortletSession(boolean cloneFromPortletSession) {
this.cloneFromPortletSession = cloneFromPortletSession;
}
public boolean isUseApplicationScopePortletSession() {
return useApplicationScopePortletSession;
}
public void setUseApplicationScopePortletSession(
boolean useApplicationScopePortletSession) {
this.useApplicationScopePortletSession = useApplicationScopePortletSession;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -