欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SSO - CAS:不拦截指定url过滤

程序员文章站 2022-03-08 20:10:57
...

首先我们看一下我们客户端中web.xml中的拦截器配置

    <filter>
        <filter-name>CASFilter</filter-name>
        <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
        <init-param>
            <param-name>casServerLoginUrl</param-name>
            <param-value>http://ssocas.ane56.com:8080/cas/login</param-value>
        </init-param>
        <init-param>
            <param-name>serverName</param-name>
            <param-value>http://ptl.ane56.com:8080</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CASFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

重要的操作无非就是客户端jar包中的AuthenticationFilter,然后上网查了下,无非就是将这个拦截方法重写。

反编译一下

SSO - CAS:不拦截指定url过滤

然后将该拦截器贴一下

package org.jasig.cas.client.authentication;

import java.io.IOException;
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.logging.Log;
import org.jasig.cas.client.util.AbstractCasFilter;
import org.jasig.cas.client.util.CommonUtils;
import org.jasig.cas.client.validation.Assertion;

public class AuthenticationFilter extends AbstractCasFilter
{
  private String casServerLoginUrl;
  private boolean renew = false;

  private boolean gateway = false;

  private GatewayResolver gatewayStorage = new DefaultGatewayResolverImpl();

  protected void initInternal(FilterConfig filterConfig) throws ServletException {
    if (!isIgnoreInitConfiguration()) {
      super.initInternal(filterConfig);
      setCasServerLoginUrl(getPropertyFromInitParams(filterConfig, "casServerLoginUrl", null));
      this.log.trace("Loaded CasServerLoginUrl parameter: " + this.casServerLoginUrl);
      setRenew(parseBoolean(getPropertyFromInitParams(filterConfig, "renew", "false")));
      this.log.trace("Loaded renew parameter: " + this.renew);
      setGateway(parseBoolean(getPropertyFromInitParams(filterConfig, "gateway", "false")));
      this.log.trace("Loaded gateway parameter: " + this.gateway);

      String gatewayStorageClass = getPropertyFromInitParams(filterConfig, "gatewayStorageClass", null);

      if (gatewayStorageClass != null)
        try {
          this.gatewayStorage = ((GatewayResolver)Class.forName(gatewayStorageClass).newInstance());
        } catch (Exception e) {
          this.log.error(e, e);
          throw new ServletException(e);
        }
    }
  }

  public void init()
  {
    super.init();
    CommonUtils.assertNotNull(this.casServerLoginUrl, "casServerLoginUrl cannot be null.");
  }

  public final void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest)servletRequest;
    HttpServletResponse response = (HttpServletResponse)servletResponse;
    HttpSession session = request.getSession(false);
    Assertion assertion = session != null ? (Assertion)session.getAttribute("_const_cas_assertion_") : null;

    if (assertion != null) {
      filterChain.doFilter(request, response);
      return;
    }

    String serviceUrl = constructServiceUrl(request, response);
    String ticket = CommonUtils.safeGetParameter(request, getArtifactParameterName());
    boolean wasGatewayed = this.gatewayStorage.hasGatewayedAlready(request, serviceUrl);

    if ((CommonUtils.isNotBlank(ticket)) || (wasGatewayed)) {
      filterChain.doFilter(request, response);
      return;
    }

    this.log.debug("no ticket and no assertion found");
    String modifiedServiceUrl;
    String modifiedServiceUrl;
    if (this.gateway) {
      this.log.debug("setting gateway attribute in session");
      modifiedServiceUrl = this.gatewayStorage.storeGatewayInformation(request, serviceUrl);
    } else {
      modifiedServiceUrl = serviceUrl;
    }

    if (this.log.isDebugEnabled()) {
      this.log.debug("Constructed service url: " + modifiedServiceUrl);
    }

    String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway);

    if (this.log.isDebugEnabled()) {
      this.log.debug("redirecting to \"" + urlToRedirectTo + "\"");
    }

    response.sendRedirect(urlToRedirectTo);
  }

  public final void setRenew(boolean renew) {
    this.renew = renew;
  }

  public final void setGateway(boolean gateway) {
    this.gateway = gateway;
  }

  public final void setCasServerLoginUrl(String casServerLoginUrl) {
    this.casServerLoginUrl = casServerLoginUrl;
  }

  public final void setGatewayStorage(GatewayResolver gatewayStorage) {
    this.gatewayStorage = gatewayStorage;
  }
}

   我们重新定义一个类ReAuthenticationFilter,也继承AbstractCasFilter类,在该类中完全复制AuthenticationFilter类中的内容,并在我们自己的拦截器做如下修改:

 1.增加excepPaths属性,用于存放要排除过滤的路径,采用数组方式存放,应对多个url头的拦截。

private String[] excludePaths;

 2.修改initInternal方法、从web.xml配置中解析出要排除过滤的路径

 protected void initInternal(final FilterConfig filterConfig) throws ServletException {
        if (!isIgnoreInitConfiguration()) {
            super.initInternal(filterConfig);
            setCasServerLoginUrl(getPropertyFromInitParams(filterConfig, "casServerLoginUrl", null));
            log.trace("Loaded CasServerLoginUrl parameter: " + this.casServerLoginUrl);
            setRenew(parseBoolean(getPropertyFromInitParams(filterConfig, "renew", "false")));
            log.trace("Loaded renew parameter: " + this.renew);
            setGateway(parseBoolean(getPropertyFromInitParams(filterConfig, "gateway", "false")));
            log.trace("Loaded gateway parameter: " + this.gateway);
            final String gatewayStorageClass = getPropertyFromInitParams(filterConfig, "gatewayStorageClass", null);
            if (gatewayStorageClass != null) {
                try {
                    this.gatewayStorage = (GatewayResolver) Class.forName(gatewayStorageClass).newInstance();
                } catch (final Exception e) {
                    log.error(e,e);
                    throw new ServletException(e);
                }
            }


            //拦截器过滤修改************begin*************************
            String _excludePaths = getPropertyFromInitParams(filterConfig, "excepPaths", null);
            if(CommonUtils.isNotBlank(_excludePaths)){
             setExcludePaths(_excludePaths.trim().split(","));
            }
            //拦截器过滤修改************end************************
        }
    }

 3.修改doFilter方法、判断请求路径是否需要过滤

    public final void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException {
        final HttpServletRequest request = (HttpServletRequest) servletRequest;
        final HttpServletResponse response = (HttpServletResponse) servletResponse;
        final HttpSession session = request.getSession(false);
        final Assertion assertion = session != null ? (Assertion) session.getAttribute(CONST_CAS_ASSERTION) : null;


        //拦截器过滤修改************begin********************
        boolean isAir = request.getParameter("isAir")!=null && "true".equals(request.getParameter("isAir"));
        if (isAir ) {
            filterChain.doFilter(request, response);
        }

        String uri = request.getRequestURI()+request.getQueryString;
        boolean isInWhiteList = false;
        if(excludePaths!=null && excludePaths.length>0 && uri!=null){
            for(String path : excludePaths){
             if(CommonUtils.isNotBlank(path)){
              isInWhiteList = uri.indexOf(path.trim())>-1;
               if(isInWhiteList){
                 break;
               }
              }
            }
        }
        
        if(isInWhiteList){
            filterChain.doFilter(request, response);
            return;
           }
        //拦截器过滤修改************end********************************
        
        if (assertion != null) {
            filterChain.doFilter(request, response);
            return;
        }
        final String serviceUrl = constructServiceUrl(request, response);
        final String ticket = CommonUtils.safeGetParameter(request,getArtifactParameterName());
        final boolean wasGatewayed = this.gatewayStorage.hasGatewayedAlready(request, serviceUrl);
        if (CommonUtils.isNotBlank(ticket) || wasGatewayed) {
            filterChain.doFilter(request, response);
            return;
        }
        final String modifiedServiceUrl;
        log.debug("no ticket and no assertion found");
        if (this.gateway) {
            log.debug("setting gateway attribute in session");
            modifiedServiceUrl = this.gatewayStorage.storeGatewayInformation(request, serviceUrl);
        } else {
            modifiedServiceUrl = serviceUrl;
        }
        if (log.isDebugEnabled()) {
            log.debug("Constructed service url: " + modifiedServiceUrl);
        }
        final String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway);
        if (log.isDebugEnabled()) {
            log.debug("redirecting to \"" + urlToRedirectTo + "\"");
        }
        response.sendRedirect(urlToRedirectTo);
    }

   4.修改完以上方法、则web.xml中还需要修改两点,修改后的web.xml配置如下:

    <filter>
        <filter-name>CASFilter</filter-name>
        <filter-class>org.jasig.cas.client.authentication.ReAuthenticationFilter</filter-class>
        <init-param>
            <param-name>casServerLoginUrl</param-name>
            <param-value>http://ssocas.ane56.com:8080/cas/login</param-value>
        </init-param>
        <init-param>
            <param-name>serverName</param-name>
            <param-value>http://ptl.ane56.com:8080</param-value>
        </init-param>
        <init-param>
           <description>cas not filter url</description>
           <param-name>exceptPaths</param-name>
           <param-value>isAir=true,/user/login</param-value>
        </init-param>
    </filter>

惯例图示

SSO - CAS:不拦截指定url过滤

ps:关于request取url参考:     http://zjutsoft.iteye.com/blog/1084260

从request获取各种路径总结 
request.getRealPath("url"); // 虚拟目录映射为实际目录


request.getRealPath("./");    // 网页所在的目录

request.getRealPath("../"); // 网页所在目录的上一层目录

request.getContextPath();    // 应用的web目录的名称


http://localhost:7001/bookStore/ 
/bookStore/ => [contextPath] (request.getContextPath())

获取Web项目的全路径 
String strDirPath = request.getSession().getServletContext().getRealPath("/");

以工程名为TEST为例:

(1)得到包含工程名的当前页面全路径:request.getRequestURI() 
结果:/TEST/test.jsp


(2)得到工程名:request.getContextPath() 
结果:/TEST


(3)得到当前页面所在目录下全名称:request.getServletPath() 
结果:如果页面在jsp目录下 /TEST/jsp/test.jsp


(4)得到页面所在服务器的全路径:application.getRealPath("页面.jsp") 
结果:D:\resin\webapps\TEST\test.jsp


(5)得到页面所在服务器的绝对路径:absPath=new java.io.File(application.getRealPath(request.getRequestURI())).getParent(); 
结果:D:\resin\webapps\TEST

2.在类中取得路径:

(1)类的绝对路径:Class.class.getClass().getResource("/").getPath() 
结果:/D:/TEST/WebRoot/WEB-INF/classes/pack/


(2)得到工程的路径:System.getProperty("user.dir") 
结果:D:\TEST

3.在Servlet中取得路径:

(1)得到工程目录:request.getSession().getServletContext().getRealPath("") 参数可具体到包名。 
结果:E:\Tomcat\webapps\TEST


(2)得到IE地址栏地址:request.getRequestURL() 
结果:http://localhost:8080/TEST/test


(3)得到相对地址:request.getRequestURI() 
结果:/TEST/test

相关标签: cas