Package org.beangle.security.monitor.web

Source Code of org.beangle.security.monitor.web.SecurityFilter

//$Id: CheckAuthorityFilter.java,v 1.6 2007/01/13 07:06:51 chaostone Exp $
/*
*
* Copyright c 2005-2009
* Licensed under the Apache License, Version 2.0 (the "License")
* http://www.apache.org/licenses/LICENSE-2.0
*
*/
/********************************************************************************
* @author duyaming,duantihua
*
* MODIFICATION DESCRIPTION
*
* Name                 Date                Description
* ============         ============        ============
* duyaming              2005-10-21         Created
* duantihua             2006-2-8           add comment& head
********************************************************************************/

package org.beangle.security.monitor.web;

import java.io.IOException;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;

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.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;
import org.beangle.security.monitor.Authentication;
import org.beangle.security.monitor.AuthenticationException;
import org.beangle.security.monitor.OnlineActivity;
import org.beangle.security.monitor.auth.provider.sso.SsoAuthentication;
import org.beangle.security.monitor.auth.ui.UserDetailsSource;
import org.beangle.security.monitor.auth.web.WebUserDetailsSource;
import org.beangle.security.monitor.SecurityManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

/**
* 权限过滤器<br>
*
* @author chaostone 主要根据请求链接的最后的*.do判断该action是否在用户的权限范围内.
*         不用考虑的权限模块定义在同一级的IgnoreAction.properties文件里.
*/
public class SecurityFilter implements Filter {

  private final static Logger logger = LoggerFactory.getLogger(SecurityFilter.class);

  public static String PREVIOUS_URL = "previousURL";

  private SecurityManager manager;

  private String loginFailPath = null;

  private String noAuthorityPath = null;

  private String expiredPath = null;

  /** 功能点提取类名 */
  private String resourceExtractorClassName = DefaultResourceExtractor.class.getName();

  private ResourceExtractor resourceExtractor;

  private Set<String> freeResources = new HashSet<String>();

  private UserDetailsSource userDetailsSource = new WebUserDetailsSource();

  public void init(FilterConfig cfg) throws ServletException {
    @SuppressWarnings("unchecked")
    Enumeration<String> en = cfg.getInitParameterNames();
    while (en.hasMoreElements()) {
      String property = en.nextElement();
      Object value = cfg.getInitParameter(property);
      try {
        PropertyUtils.setProperty(this, property, value);
      } catch (Exception e) {
        throw new RuntimeException(e.getMessage());
      }
    }
    // 初始化功能点提取器
    if (StringUtils.isEmpty(resourceExtractorClassName)) {
      resourceExtractorClassName = SimpleResourceExtractor.class.getName();
    }
    try {
      resourceExtractor = (ResourceExtractor) Class.forName(resourceExtractorClassName)
          .newInstance();
    } catch (Exception e) {
      throw new RuntimeException(e.getMessage());
    }

    if (StringUtils.isEmpty(expiredPath)) {
      expiredPath = loginFailPath;
    }
    freeResources.add(resourceExtractor.extract(loginFailPath));
    freeResources.add(resourceExtractor.extract(expiredPath));
    if (null != noAuthorityPath) {
      freeResources.add(resourceExtractor.extract(noAuthorityPath));
    }
    logger.info("Filter {} configured successfully with free resources {}",
        cfg.getFilterName(), freeResources);
  }

  /**
   * 实施过滤
   */
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    HttpServletRequest httpRequest = ((HttpServletRequest) request);
    String resource = resourceExtractor.extract(httpRequest);
    request.setAttribute("resourceName", resource);
    HttpSession session = httpRequest.getSession(true);
    if (null == manager) {
      WebApplicationContext wac = WebApplicationContextUtils
          .getRequiredWebApplicationContext(session.getServletContext());
      manager = (SecurityManager) wac.getBean("securityManager", SecurityManager.class);
    }
    // 避免login没有权限,出现死循环
    if (!freeResources.contains(resource) && !manager.isPublicResource(resource)) {
      OnlineActivity info = manager.getAuthenticationManager().getSessionController()
          .getOnlineActivity(session.getId());
      if (null == info) {
        Authentication auth = null;
        // remember me
//        if (manager.isEnableRememberMe()) {
//          auth = manager.getRememberMeService().autoLogin(httpRequest);
//        }
        if (null == auth) {
          auth = new SsoAuthentication(httpRequest);
          auth.setDetails(userDetailsSource.buildDetails(httpRequest));
        }
        try {
          manager.authenticate(auth);
        } catch (AuthenticationException e) {
          // 记录访问失败的URL
          session.setAttribute(PREVIOUS_URL, httpRequest.getRequestURL() + "?"
              + httpRequest.getQueryString());
          redirectTo((HttpServletRequest) request, (HttpServletResponse) response,
              loginFailPath);
          return;
        }
      } else if (info.isExpired()) {
        manager.logout(session);
        // 记录访问失败的URL
        session.setAttribute(PREVIOUS_URL, httpRequest.getRequestURL() + "?"
            + httpRequest.getQueryString());
        redirectTo((HttpServletRequest) request, (HttpServletResponse) response,
            expiredPath);
        return;
      } else {
        info.refreshLastRequest();
        boolean pass = manager.isAuthorized(info.getUserid(), resource);
        if (pass) {
          logger.debug("user {} access {} success", info.getPrincipal(), resource);
        } else {
          logger.info("user {} cannot access [{}]", info.getPrincipal(), resource);
          reportNoAuthority((HttpServletRequest) request, (HttpServletResponse) response);
          return;
        }
      }
    } else {
      logger.debug("free or public resource {} was accessed", resource);
    }
    chain.doFilter(request, response);
  }

  private void reportNoAuthority(HttpServletRequest request, HttpServletResponse response)
      throws IOException {
    if (null == noAuthorityPath) {
      response.getWriter().append("no authority");
    } else {
      redirectTo((HttpServletRequest) request, (HttpServletResponse) response,
          noAuthorityPath);
    }
  }

  public void redirectTo(HttpServletRequest request, HttpServletResponse response, String path)
      throws IOException {
    if (!path.startsWith("/")) {
      String contextPath = request.getContextPath();
      ((HttpServletResponse) response).sendRedirect((contextPath.equals("/") ? ""
          : (contextPath + "/"))
          + path);
    } else {
      ((HttpServletResponse) response).sendRedirect(path);
    }
  }

  public void destroy() {
  }

  public String getLoginFailPath() {
    return loginFailPath;
  }

  public void setLoginFailPath(String failRedirect) {
    this.loginFailPath = failRedirect;
  }

  public String getNoAuthorityPath() {
    return noAuthorityPath;
  }

  public void setNoAuthorityPath(String noAuthorityRedirect) {
    this.noAuthorityPath = noAuthorityRedirect;
  }

  public String getExpiredPath() {
    return expiredPath;
  }

  public void setExpiredPath(String expiredPath) {
    this.expiredPath = expiredPath;
  }

  public String getResourceExtractorClassName() {
    return resourceExtractorClassName;
  }

  public void setResourceExtractorClassName(String resourceExtractorClassName) {
    this.resourceExtractorClassName = resourceExtractorClassName;
  }

}
TOP

Related Classes of org.beangle.security.monitor.web.SecurityFilter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.