⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 securityfilter.java

📁 用于JAVA的Web的权限过滤器
💻 JAVA
字号:
package dev.trade.common.securityfilter.filter;

import java.io.*;
import java.net.*;
import java.security.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.log4j.*;
import dev.trade.common.securityfilter.util.*;
import dev.trade.common.securityfilter.authenticator.*;
import dev.trade.common.securityfilter.authenticator.Authenticator;
import dev.trade.common.securityfilter.config.*;

/**
 * <p>Title: 权限过滤器</p>
 *
 * <p>Description: 权限过滤器主类,需要配置到Web.xml文件中才会起作用,配置示例如下:</p>
 * <filter>
 *   <filter-name>SecurityFilter</filter-name>
 *   <filter-class>dev.trade.common.securityfilter.filter.SecurityFilter</filter-class>
 *   <init-param>
 *     <param-name>config</param-name>
 *     <param-value>/WEB-INF/securityfilter-config.xml</param-value>
 *     <description>Configuration file location (default)</description>
 *   </init-param>
 * </filter>
 * <filter-mapping>
 * <filter-name>SecurityFilter</filter-name>
 *   <url-pattern>/*</url-pattern>
 * </filter-mapping>
 *
 * <p>Copyright: Copyright (c) 2006</p>
 *
 * <p>Company: </p>
 *
 * @author Zheng YanNan
 * @version 1.0
 */
public class SecurityFilter implements Filter{
  private static Logger log = Logger.getLogger(SecurityFilter.class);

  public static final String CONFIG_FILE_KEY = "config";
  public static final String DEFAULT_CONFIG_FILE = "/WEB-INF/securityfilter-config.xml";
  public static final String VALIDATE_KEY = "validate";
  public static final String TRUE = "true";

  protected FilterConfig config;
  protected List patternList;
  protected URLPatternFactory patternFactory;
  protected Authenticator authenticator;
  protected SecurityConfig securityConfig;

  /**
   * 初始化权限过滤器
   * @param config filter configuration object
   */
  public void init(FilterConfig config) throws ServletException{
    this.config = config;
    String configFile = null;
    try{
      // 解析配置文件
      configFile = config.getInitParameter(CONFIG_FILE_KEY);
      if(configFile == null){
        configFile = DEFAULT_CONFIG_FILE;
      }
      URL configURL = config.getServletContext().getResource(configFile);
//         // validate config file?
//         boolean validate = TRUE.equalsIgnoreCase(config.getInitParameter(VALIDATE_KEY));
      securityConfig = new SecurityConfig(false);
      securityConfig.loadConfig(configURL);

      // 创建验证器
      authenticator = AuthenticatorFactory.createAuthenticator(config, securityConfig);

      // 创建范式列表
      patternFactory = new URLPatternFactory();
      patternList = new ArrayList();
      int order = 1;
      List constraints = securityConfig.getSecurityConstraints();
      for(Iterator cIter = constraints.iterator(); cIter.hasNext(); ){
        SecurityConstraint constraint = (SecurityConstraint)cIter.next();
        for(Iterator rIter = constraint.getWebResourceCollections().iterator(); rIter.hasNext(); ){
          WebResourceCollection resourceCollection = (WebResourceCollection)rIter.next();
          for(Iterator pIter = resourceCollection.getURLPatterns().iterator(); pIter.hasNext(); ){
            URLPattern pattern = patternFactory.createURLPattern((String)pIter.next(),
                                 constraint, resourceCollection, order++);
            patternList.add(pattern);
          }
        }
      }
      Collections.sort(patternList);
    } catch(java.io.IOException ioe){
      log.error("无法打开配置文件:" + configFile, ioe);
      throw new ServletException("无法打开配置文件:" + configFile,ioe);
    } catch(org.xml.sax.SAXException se){
      log.error("无法解析配置文件:" + configFile, se);
      throw new ServletException("无法解析配置文件:" + configFile,se);
    } catch(Exception e){
      log.error("发生错误!" + e);
      throw new ServletException("发生错误:",e);
    }
  }

  /**
   * 权限过滤
   * @param request ServletRequest
   * @param response ServletResponse
   * @param chain FilterChain
   * @throws IOException
   * @throws ServletException
   */
  public void doFilter(ServletRequest request, ServletResponse response,
      FilterChain chain) throws IOException, ServletException{
    HttpServletRequest hReq = (HttpServletRequest)request;
    HttpServletResponse hRes = (HttpServletResponse)response;
    SecurityRequest wrappedRequest;

    // 检查请求是否已被验证过(减少验证次数)
    if(!TRUE.equals(request.getAttribute(RequestUtils.ALREADY_PROCESSED))){
      // 设置已验证标记
      request.setAttribute(RequestUtils.ALREADY_PROCESSED, TRUE);
      // 创建一个URL匹配器
      URLPatternMatcher patternMatcher = patternFactory.createURLPatternMatcher();
      // 获取已保存的请求,否则返回空(主要用于登录后跳转回原请求URL)
      SavedRequest savedRequest = RequestUtils.getSavedRequest(hReq);

      // 包装当前请求
      wrappedRequest = new SecurityRequest(hReq, savedRequest, authenticator);

      URLPattern match = null;
      try{
        // 检查是否为登出请求,并进行相应处理
        if(authenticator.checkAndDoLogout(wrappedRequest, hRes, patternMatcher)){
          // If logging out destroy and recreate session
          hReq.getSession().invalidate();
          hReq.getSession(true);
        }

        // 检查是否为登录提交请求,并进行相应处理
        if(authenticator.checkAndDoLogin(wrappedRequest, hRes, patternMatcher)){
          return;
        }

        // 检查是否需要跳过权限验证
        if(!authenticator.bypassSecurityForThisRequest(wrappedRequest, patternMatcher)){
          // check if request matches security constraint
          match = matchPattern(wrappedRequest.getMatchableURL(), wrappedRequest.getMethod(), patternMatcher);
        }
      } catch(Exception e){
        throw new ServletException("URL匹配错误:" + wrappedRequest.getMatchableURL(), e);
      }

      // 检查当前请求的权限约束
      if(match != null){
        AuthConstraint authConstraint = match.getSecurityConstraint().getAuthConstraint();
        if(authConstraint != null){
          Collection roles = authConstraint.getRoles();
          Principal principal = wrappedRequest.getUserPrincipal();
          // 如果允许的角色列表为空, 所有的请求都通过, 可以跳过登录
          if(!roles.isEmpty() && principal == null){
            // user needs to be authenticated
            try{
              authenticator.showLogin(hReq, hRes);
            } catch(Exception ex){
              throw new ServletException("登录页面转向失败:" + wrappedRequest.getMatchableURL(), ex);
            }
            return;
          } else{
            boolean authorized = roles.isEmpty();
            for(Iterator i = roles.iterator(); i.hasNext() && !authorized; ){
              String role = (String)i.next();
              // TODO: if *, do you need to have at least one role to be authorized?
              // if so, we need to iterate through the roles defined in config file or change the
              // realm inteface to get a list of roles for the user (both solutions are undesireable)
              if("*".equals(role) || authenticator.isUserInRole(principal, role)){
                authorized = true;
              }
            }
            if(!authorized){
              // 访问被禁止(没有权限)
              try{
                authenticator.showForbidden(hReq, hRes);
              } catch(Exception ex){
                throw new ServletException("访问禁止页面转向失败:" + wrappedRequest.getMatchableURL(), ex);
              }
              return;
            }
          }
        }
      }
      // send wrapped request down the chain
      request = wrappedRequest;
    }
    chain.doFilter(request, response);
  }

  /**
   * Destroy the filter, releasing resources.
   */
  public void destroy(){
  }


  /**
   * 查找符合请求URL 与 请求方法的URL范式
   * @param pattern String
   * @param httpMethod String
   * @param matcher URLPatternMatcher
   * @return URLPattern
   * @throws Exception
   */
  protected URLPattern matchPattern(String pattern, String httpMethod,
      URLPatternMatcher matcher) throws Exception{
    // PERFORMANCE IMPROVEMENT OPPORTUNITY: cahce pattern matches
    Iterator i = patternList.iterator();
    URLPattern urlPattern = null;
    while(i.hasNext()){
      urlPattern = (URLPattern)i.next();
      if(matcher.match(pattern, httpMethod, urlPattern)){
        return urlPattern;
      }
    }
    return null;
  }

  /**
   * Set the filter configuration, included for WebLogic 6 compatibility.
   *
   * @param config filter configuration object
   */
  public void setFilterConfig(FilterConfig config) throws ServletException{
    init(config);
  }

  /**
   * Get the filter config object, included for WebLogic 6 compatibility.
   */
  public FilterConfig getFilterConfig(){
    return config;
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -