acegi security实践教程—简单定制logoutFilter


  回顾:

    logoutFilter过滤器,我已经带大家了解过了。其中注销是由handler.logout完成的。这就需要在配置文件中配置具体的handler,比如securitycontextlogouthandler,或者tokenbasedremembermeservices,大家可以看到logouthandler具体的实现类如下:
 
  
  若我程序中就想只用SecurityContextLogoutHandler,对于利用cookie自动登录的效果暂时不需要,我们应该如何做呢?
  第一:利用上篇博客的做法,在list中只配置SecurityContextLogoutHandler
  第二:重写这个logoutFilter,程序中使用自己的过滤器。
  
  因为上篇博客已经讲解了关键代码,其实那几句关键代码几乎就是整个类代码了。这篇博客同上篇博客的作用一样,实现注销功能,只不过是利用自己Filter而已。

  具体开发步骤:

  开发环境:

acegi security实践教程—简单定制logoutFilter_第1张图片

   配置文件:




	
	
	
	
		
			
				PATTERN_TYPE_APACHE_ANT
				/**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
			
		
	
   	
		
   		
    
    
      
    
   		
   
       
        
          
        
          
        
          
        
          
     
	
	
		
			
				
			
		
	
	
	
    
	
		
	

    
	
		
			
				test=1,ROLE_USER
				lisi=1,ROLE_SUPERVISOR
				zhangsan=1,ROLE_SUPERVISOR,disabled
			
		
	
	
	
   
       
          
              
                  
                  
              
         
      
          
              
                  
              
          
          
	
   
		
		
		
			
		
	

	
		
			
				
			
		
	

  自己的Filter:

package com.extend;
	/* 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.
	 */

	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;
import javax.servlet.http.HttpSession;

	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;

	/**
	 * Logs a principal out.
	 * 

* 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 TokenBasedRememberMeServices and * SecurityContextLogoutHandler (in that order). *

*

* After logout, the URL specified by {@link #logoutSuccessUrl} will be shown. *

*

* Do not use this class directly. Instead configure web.xml to use the * {@link org.acegisecurity.util.FilterToBeanProxy}. *

* * @author Ben Alex * @version $Id: LogoutFilter.java 1967 2007-08-28 11:37:05Z luke_t $ */ public class MyLogoutFilter implements Filter { //~ Static fields/initializers ===================================================================================== //~ Instance fields ================================================================================================ private String filterProcessesUrl = "/j_acegi_logout"; private String logoutSuccessUrl; //~ 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(); HttpSession session = httpRequest.getSession(false); if (session != null) { session.invalidate(); } SecurityContextHolder.clearContext(); 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 take place. * * @param request the request * @param response the response * * @return true if logout should occur, false otherwise */ protected boolean requiresLogout(HttpServletRequest request, HttpServletResponse response) { String uri = request.getRequestURI(); int pathParamIndex = uri.indexOf(';'); if (pathParamIndex > 0) { // strip everything from the first semi-colon uri = uri.substring(0, pathParamIndex); } int queryParamIndex = uri.indexOf('?'); if (queryParamIndex > 0) { // strip everything from the first question mark uri = uri.substring(0, queryParamIndex); } if ("".equals(request.getContextPath())) { return uri.endsWith(filterProcessesUrl); } 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; } protected String getFilterProcessesUrl() { return filterProcessesUrl; } public String getLogoutSuccessUrl() { return logoutSuccessUrl; } public void setLogoutSuccessUrl(String logoutSuccessUrl) { this.logoutSuccessUrl = logoutSuccessUrl; } }

  项目下载:

  ps:哈哈,这个logoutFilter说白了就是自己改写的,这样的话,配置文件中只配置注销后转向的页面即可。至于如何改写的,这个大家看一眼源码即可,害羞的速速略过啦~

  预告:

  前几篇完成了一个小雏形,至于这篇算小插曲吧,前几篇从数据库读取用户身份信息是基于内存形式,而非真正数据库中,为了进一步完善,接下来我们开始设计自己的系统或者如何嵌入现有系统。
  

你可能感兴趣的:(【Acegi】,acegi,security实践教程)