001: /******************************************************************************
002: * JBoss, a division of Red Hat *
003: * Copyright 2006, Red Hat Middleware, LLC, and individual *
004: * contributors as indicated by the @authors tag. See the *
005: * copyright.txt in the distribution for a full listing of *
006: * individual contributors. *
007: * *
008: * This is free software; you can redistribute it and/or modify it *
009: * under the terms of the GNU Lesser General Public License as *
010: * published by the Free Software Foundation; either version 2.1 of *
011: * the License, or (at your option) any later version. *
012: * *
013: * This software is distributed in the hope that it will be useful, *
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of *
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
016: * Lesser General Public License for more details. *
017: * *
018: * You should have received a copy of the GNU Lesser General Public *
019: * License along with this software; if not, write to the Free *
020: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
021: * 02110-1301 USA, or see the FSF site: http://www.fsf.org. *
022: ******************************************************************************/package org.jboss.portal.server.aspects.server;
023:
024: import org.apache.log4j.Logger;
025: import org.jboss.portal.common.invocation.InvocationException;
026: import org.jboss.portal.server.ServerInterceptor;
027: import org.jboss.portal.server.ServerInvocation;
028: import org.jboss.portal.server.ServerInvocationContext;
029: import org.jboss.portal.web.RequestDispatchCallback;
030: import org.jboss.portal.web.ServletContainer;
031: import org.jboss.portal.web.ServletContainerFactory;
032:
033: import javax.servlet.ServletContext;
034: import javax.servlet.ServletException;
035: import javax.servlet.http.HttpServletRequest;
036: import javax.servlet.http.HttpServletResponse;
037: import javax.servlet.http.HttpSession;
038: import java.io.IOException;
039: import java.util.HashSet;
040: import java.util.Iterator;
041: import java.util.Set;
042:
043: /**
044: * This interceptor implementation is used to keep track of all webapp the current user has used during its portal
045: * session. When the invocation is tagged for a signout then it performs an additional task of invalidating the sessions
046: * of the webapp that have been collected during the portal session as well as invalidating the current portal session.
047: *
048: * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
049: * @version $Revision: 8784 $
050: */
051: public class SignOutInterceptor extends ServerInterceptor {
052:
053: /** . */
054: private static final Invalidation invalidator = new Invalidation();
055:
056: /** . */
057: private static final Logger log = Logger
058: .getLogger(SignOutInterceptor.class);
059:
060: /** . */
061: private static final String KEY = "org.jboss.portal.session.contexts";
062:
063: /** . */
064: private static final ThreadLocal localContexts = new ThreadLocal() {
065: protected Object initialValue() {
066: return new HashSet();
067: }
068: };
069:
070: public static Set getSet() {
071: return (Set) localContexts.get();
072: }
073:
074: /** . */
075: private ServletContainerFactory servletContainerFactory;
076:
077: public ServletContainerFactory getServletContainerFactory() {
078: return servletContainerFactory;
079: }
080:
081: public void setServletContainerFactory(
082: ServletContainerFactory servletContainerFactory) {
083: this .servletContainerFactory = servletContainerFactory;
084: }
085:
086: protected void invoke(ServerInvocation invocation)
087: throws Exception, InvocationException {
088: try {
089: getSet().clear();
090:
091: //
092: invocation.invokeNext();
093: } finally {
094: after(invocation);
095: }
096: }
097:
098: private void after(ServerInvocation invocation) {
099: // Put the contexts that have been used during this invocation into the global set
100: ServerInvocationContext context = invocation.getServerContext();
101: HttpSession session = context.getClientRequest().getSession();
102: Set contexts = (Set) session.getAttribute(KEY);
103: if (contexts == null) {
104: contexts = new HashSet();
105: session.setAttribute(KEY, contexts);
106: }
107: contexts.addAll(getSet());
108: getSet().clear();
109:
110: // If the invocation has been set to signout then perform the invalidations
111: if (invocation.getResponse().getWantSignOut()) {
112: // Get portal context
113: ServletContext portalContext = session.getServletContext();
114:
115: //
116: HttpServletRequest req = invocation.getServerContext()
117: .getClientRequest();
118:
119: //
120: HttpServletResponse resp = invocation.getServerContext()
121: .getClientResponse();
122:
123: // Iterate over all the context that have been used
124: for (Iterator i = contexts.iterator(); i.hasNext();) {
125: String dispatchContextName = (String) i.next();
126:
127: // Get the context
128: ServletContext dispatchContext = portalContext
129: .getContext(dispatchContextName);
130:
131: // The context could be null if the web app has been removed after the web app has been tracked
132: if (dispatchContext != null) {
133: try {
134: ServletContainer servletContainer = servletContainerFactory
135: .getServletContainer();
136:
137: // Execute the command that invalidates the session
138: servletContainer.include(dispatchContext, req,
139: resp, invalidator, null);
140: } catch (Exception e) {
141: log
142: .error(
143: "An error occured when trying to invalidate the session",
144: e);
145: }
146: }
147: }
148:
149: //Finally invalidate this session
150: try {
151: session.invalidate();
152: } catch (IllegalStateException stateException) {
153: if (stateException.toString().indexOf(
154: "invalidate: Session already invalidated") != -1) {
155: //This means Tomcat SSO is probably turned on and part of invalidating the other war context's
156: //session, this Portal's session has been invalidated as well
157:
158: //No need to do anything
159: } else {
160: //This is a real issue, don't eat this
161: throw stateException;
162: }
163: }
164:
165: // Set information about logout
166: req.setAttribute("org.jboss.portal.logout", "true");
167: }
168: }
169:
170: public static class Invalidation implements RequestDispatchCallback {
171: public Object doCallback(ServletContext servletContext,
172: HttpServletRequest req, HttpServletResponse resp,
173: Object handback) throws ServletException, IOException {
174: HttpSession session = req.getSession(false);
175:
176: //
177: if (session != null) {
178: session.invalidate();
179: }
180:
181: //
182: return null;
183: }
184: }
185: }
|