11 changed files with 318 additions and 16 deletions
@ -0,0 +1,178 @@
@@ -0,0 +1,178 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.acegisecurity.ui.logout; |
||||
|
||||
import org.acegisecurity.Authentication; |
||||
|
||||
import org.acegisecurity.context.SecurityContextHolder; |
||||
|
||||
import org.apache.commons.logging.Log; |
||||
import org.apache.commons.logging.LogFactory; |
||||
|
||||
import org.springframework.util.Assert; |
||||
|
||||
import java.io.IOException; |
||||
|
||||
import javax.servlet.Filter; |
||||
import javax.servlet.FilterChain; |
||||
import javax.servlet.FilterConfig; |
||||
import javax.servlet.ServletException; |
||||
import javax.servlet.ServletRequest; |
||||
import javax.servlet.ServletResponse; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
|
||||
|
||||
/** |
||||
* Logs a principal out. |
||||
* |
||||
* <p> |
||||
* Polls a series of {@link LogoutHandler}s. The handlers should be specified |
||||
* in the order they are required. Generally you will want to call logout |
||||
* handlers <code>TokenBasedRememberMeServices</code> and |
||||
* <code>SecurityContextLogoutHandler</code> (in that order). |
||||
* </p> |
||||
* |
||||
* <p> |
||||
* After logout, the URL specified by {@link #logoutSuccessUrl} will be shown. |
||||
* </p> |
||||
* |
||||
* <p> |
||||
* <b>Do not use this class directly.</b> Instead configure |
||||
* <code>web.xml</code> to use the {@link |
||||
* org.acegisecurity.util.FilterToBeanProxy}. |
||||
* </p> |
||||
* |
||||
* @author Ben Alex |
||||
* @version $Id$ |
||||
*/ |
||||
public class LogoutFilter implements Filter { |
||||
//~ Static fields/initializers =============================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(LogoutFilter.class); |
||||
|
||||
//~ Instance fields ========================================================
|
||||
|
||||
private String filterProcessesUrl = "/j_acegi_logout"; |
||||
private String logoutSuccessUrl; |
||||
private LogoutHandler[] handlers; |
||||
|
||||
//~ Constructors ===========================================================
|
||||
|
||||
public LogoutFilter(String logoutSuccessUrl, LogoutHandler[] handlers) { |
||||
Assert.hasText(logoutSuccessUrl, "LogoutSuccessUrl required"); |
||||
Assert.notEmpty(handlers, "LogoutHandlers are required"); |
||||
this.logoutSuccessUrl = logoutSuccessUrl; |
||||
this.handlers = handlers; |
||||
} |
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
/** |
||||
* Not used. Use IoC container lifecycle methods instead. |
||||
*/ |
||||
public void destroy() {} |
||||
|
||||
public void doFilter(ServletRequest request, ServletResponse response, |
||||
FilterChain chain) throws IOException, ServletException { |
||||
if (!(request instanceof HttpServletRequest)) { |
||||
throw new ServletException("Can only process HttpServletRequest"); |
||||
} |
||||
|
||||
if (!(response instanceof HttpServletResponse)) { |
||||
throw new ServletException("Can only process HttpServletResponse"); |
||||
} |
||||
|
||||
HttpServletRequest httpRequest = (HttpServletRequest) request; |
||||
HttpServletResponse httpResponse = (HttpServletResponse) response; |
||||
|
||||
if (requiresLogout(httpRequest, httpResponse)) { |
||||
Authentication auth = SecurityContextHolder.getContext() |
||||
.getAuthentication(); |
||||
|
||||
if (logger.isDebugEnabled()) { |
||||
logger.debug("Logging out user '" + auth |
||||
+ "' and redirecting to logout page"); |
||||
} |
||||
|
||||
if (auth != null) { |
||||
for (int i = 0; i < handlers.length; i++) { |
||||
handlers[i].logout(httpRequest, httpResponse, auth); |
||||
} |
||||
} |
||||
|
||||
sendRedirect(httpRequest, httpResponse, logoutSuccessUrl); |
||||
|
||||
return; |
||||
} |
||||
|
||||
chain.doFilter(request, response); |
||||
} |
||||
|
||||
/** |
||||
* Not used. Use IoC container lifecycle methods instead. |
||||
* |
||||
* @param arg0 ignored |
||||
* |
||||
* @throws ServletException ignored |
||||
*/ |
||||
public void init(FilterConfig arg0) throws ServletException {} |
||||
|
||||
/** |
||||
* Allow subclasses to modify when a logout should tak eplace. |
||||
* |
||||
* @param request the request |
||||
* @param response the response |
||||
* |
||||
* @return <code>true</code> if logout should occur, <code>false</code> |
||||
* otherwise |
||||
*/ |
||||
protected boolean requiresLogout(HttpServletRequest request, |
||||
HttpServletResponse response) { |
||||
String uri = request.getRequestURI(); |
||||
int pathParamIndex = uri.indexOf(';'); |
||||
|
||||
if (pathParamIndex > 0) { |
||||
// strip everything after the first semi-colon
|
||||
uri = uri.substring(0, pathParamIndex); |
||||
} |
||||
|
||||
return uri.endsWith(request.getContextPath() + filterProcessesUrl); |
||||
} |
||||
|
||||
/** |
||||
* Allow subclasses to modify the redirection message. |
||||
* |
||||
* @param request the request |
||||
* @param response the response |
||||
* @param url the URL to redirect to |
||||
* |
||||
* @throws IOException in the event of any failure |
||||
*/ |
||||
protected void sendRedirect(HttpServletRequest request, |
||||
HttpServletResponse response, String url) throws IOException { |
||||
if (!url.startsWith("http://") && !url.startsWith("https://")) { |
||||
url = request.getContextPath() + url; |
||||
} |
||||
|
||||
response.sendRedirect(response.encodeRedirectURL(url)); |
||||
} |
||||
|
||||
public void setFilterProcessesUrl(String filterProcessesUrl) { |
||||
Assert.hasText(filterProcessesUrl, "FilterProcessesUrl required"); |
||||
this.filterProcessesUrl = filterProcessesUrl; |
||||
} |
||||
} |
||||
@ -0,0 +1,27 @@
@@ -0,0 +1,27 @@
|
||||
package org.acegisecurity.ui.logout; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
|
||||
import org.acegisecurity.Authentication; |
||||
|
||||
/** |
||||
* Indicates a class that is able to participate in logout handling. |
||||
* |
||||
* <p> |
||||
* Called by {@link LogoutFilter}. |
||||
* |
||||
* @author Ben Alex |
||||
* @version $Id$ |
||||
*/ |
||||
public interface LogoutHandler { |
||||
|
||||
/** |
||||
* Causes a logout to be completed. The method must complete successfully. |
||||
* |
||||
* @param request the HTTP request |
||||
* @param response the HTTP resonse |
||||
* @param authentication the current principal details |
||||
*/ |
||||
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication); |
||||
} |
||||
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.acegisecurity.ui.logout; |
||||
|
||||
import org.acegisecurity.Authentication; |
||||
|
||||
import org.acegisecurity.context.SecurityContextHolder; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
|
||||
|
||||
/** |
||||
* Performs a logout by modifying the {@link |
||||
* org.acegisecurity.context.SecurityContextHolder}. |
||||
* |
||||
* @author Ben Alex |
||||
* @version $Id$ |
||||
*/ |
||||
public class SecurityContextLogoutHandler implements LogoutHandler { |
||||
//~ Methods ================================================================
|
||||
|
||||
/** |
||||
* Does not use any arguments. They can all be <code>null</code>. |
||||
* |
||||
* @param request not used (can be <code>null</code>) |
||||
* @param response not used (can be <code>null</code>) |
||||
* @param authentication not used (can be <code>null</code>) |
||||
*/ |
||||
public void logout(HttpServletRequest request, |
||||
HttpServletResponse response, Authentication authentication) { |
||||
SecurityContextHolder.clearContext(); |
||||
} |
||||
} |
||||
@ -1,9 +0,0 @@
@@ -1,9 +0,0 @@
|
||||
<%@ page import="javax.servlet.http.Cookie" %> |
||||
<%@ page import="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices" %> |
||||
<% |
||||
session.invalidate(); |
||||
Cookie terminate = new Cookie(TokenBasedRememberMeServices.ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY, null); |
||||
terminate.setMaxAge(0); |
||||
response.addCookie(terminate); |
||||
response.sendRedirect("index.jsp"); |
||||
%> |
||||
Loading…
Reference in new issue