zoukankan      html  css  js  c++  java
  • 自定义cas客户端核心过滤器AuthenticationFilter

            关于cas客户端的基本配置这里就不多说了,不清楚的可以参考上一篇博文:配置简单cas客户端。这里是关于cas客户端实现动态配置认证需要开发说明。

             往往业务系统中有些模块或功能是可以不需要登录就可以访问的,但是添加了cas客户端之后,通过cas客户端filter中的url-pattern来设置需要过滤的url,有时根本无法满足实际业务的需求,这里笔者就通过对cas客户端中源码的阅读,和对认证流程的理解,对cas客户端做了些改动,来实现动态配置cas客户端认证范围。

             下面是cas认证的核心配置,其中AuthenticationFilter过滤器为cas客户端核心过滤,下面的url-pattern是配置需要过滤的url,如果我们能编写该过滤器,我们就可以实现动态配置cas客户端的过滤url了。

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. <!-- cas统一认证  -->  
    2.  <filter>  
    3.     <filter-name>CASFilter</filter-name>  
    4.     <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>  
    5.     <init-param>  
    6.         <param-name>casServerLoginUrl</param-name>  
    7.         <param-value>http://localhost:8080/casServer3/login</param-value>  
    8.     </init-param>  
    9.     <init-param>  
    10.         <param-name>serverName</param-name>  
    11.         <param-value>http://localhost:8080</param-value>  
    12.     </init-param>  
    13.   </filter>  
    14.   <filter-mapping>  
    15.     <filter-name>CASFilter</filter-name>  
    16.     <url-pattern>/*</url-pattern>  
    17.   </filter-mapping>    
    18.   <filter>  
    19.     <filter-name>CAS Validation Filter</filter-name>  
    20.     <filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>  
    21.     <init-param>  
    22.         <param-name>casServerUrlPrefix</param-name>  
    23.         <param-value>http://localhost:8080/casServer3</param-value>  
    24.     </init-param>  
    25.     <init-param>  
    26.         <param-name>serverName</param-name>  
    27.         <param-value>http://localhost:8080</param-value>  
    28.     </init-param>  
    29.   </filter>  
    30.   <filter-mapping>  
    31.     <filter-name>CAS Validation Filter</filter-name>  
    32.     <url-pattern>/*</url-pattern>  
    33.   </filter-mapping>  

    思路:将配置中指向的核心过滤器,指向自己定义的过滤器,将源码中核心过滤器AuthenticationFilter的代码复制拷贝到该自定义过滤器中,然后在该过滤器中添加自己的过滤规则。

    步骤:

    1.配置并启动cas服务端,具体配置可以参考博文:搭建简单的cas认证服务

    2.新建一个web项目,然后添加cas客户端配置,具体配置可以参考博文:配置简单cas客户端

    3.导入cas客户端核心jar的源码到该web项目中,源码在cas客户端下载zip包中就有,一般为cas-client-core文件夹

    4.在项目的src中新建类AuthenticationFilter,继承org.jasig.cas.client.util.AbstractCasFilter,打开web.xml文件,找到找到cas核心过滤器的配置项CASFilter,Ctrl+左键,点击进入org.jasig.cas.client.authentication.AuthenticationFilter类中,复制类里面的全部代码到自定义的AuthenticationFilter类中。修改web.xml中cas核心过滤器配置项CASFilter中的配置,将filter-class指向刚才自定义的AuthenticationFilter类,同时在该过滤器中添加<init-param>配置。如下

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. <filter>  
    2.     <filter-name>CASFilter</filter-name>  
    3.     <filter-class>com.supre.filter.AuthenticationFilter</filter-class>  
    4.     <init-param>  
    5.         <param-name>casServerLoginUrl</param-name>  
    6.         <param-value>http://localhost:8080/casServer3/login</param-value>  
    7.     </init-param>  
    8.     <init-param>  
    9.         <param-name>serverName</param-name>  
    10.         <param-value>http://localhost:8080</param-value>  
    11.     </init-param>  
    12.     <init-param>  
    13.         <param-name>excludePaths</param-name>  
    14.         <param-value>.*[/,\]rest[/,\].*</param-value>  
    15.     </init-param>  
    16.   </filter>  
    17.   <filter-mapping>  
    18.     <filter-name>CASFilter</filter-name>  
    19.     <url-pattern>/*</url-pattern>  
    20.   </filter-mapping>   

    说明:

    1其中param-name为参数名,这个在过滤器初始化中需要根据该名字来取param-value中的值

    2其中param-value的值可以根据需要在filter中制定自己的规则,笔者这里是正则表达式

    5.在自定义的AuthenticationFilter中添加自己的代码,来实现认证范围的控制,代码如下:

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. package com.supre.filter;  
    2.   
    3. import java.io.IOException;  
    4.   
    5. import javax.servlet.FilterChain;  
    6. import javax.servlet.FilterConfig;  
    7. import javax.servlet.ServletException;  
    8. import javax.servlet.ServletRequest;  
    9. import javax.servlet.ServletResponse;  
    10. import javax.servlet.http.HttpServletRequest;  
    11. import javax.servlet.http.HttpServletResponse;  
    12. import javax.servlet.http.HttpSession;  
    13.   
    14. import org.jasig.cas.client.authentication.DefaultGatewayResolverImpl;  
    15. import org.jasig.cas.client.authentication.GatewayResolver;  
    16. import org.jasig.cas.client.util.AbstractCasFilter;  
    17. import org.jasig.cas.client.util.CommonUtils;  
    18. import org.jasig.cas.client.validation.Assertion;  
    19. /** 
    20.  * 为了方便控制filter,自定义了统一认证过滤器AuthenticationFilter 
    21.  * @author Administrator 
    22.  * 
    23.  */  
    24. public class AuthenticationFilter extends AbstractCasFilter{  
    25.      /** 
    26.      * The URL to the CAS Server login. 
    27.      */  
    28.     private String casServerLoginUrl;  
    29.   
    30.     /** 
    31.      * Whether to send the renew request or not. 
    32.      */  
    33.     private boolean renew = false;  
    34.   
    35.     /** 
    36.      * Whether to send the gateway request or not. 
    37.      */  
    38.     private boolean gateway = false;  
    39.     /** 
    40.      * 添加属性,这里用来存放不过滤地址正则表达式,可以根据自己需求定制---1 
    41.      */  
    42.     private String excludePaths;  
    43.       
    44.     private GatewayResolver gatewayStorage = new DefaultGatewayResolverImpl();  
    45.   
    46.     protected void initInternal(final FilterConfig filterConfig) throws ServletException {  
    47.         if (!isIgnoreInitConfiguration()) {  
    48.             super.initInternal(filterConfig);  
    49.             setCasServerLoginUrl(getPropertyFromInitParams(filterConfig, "casServerLoginUrl", null));  
    50.             log.trace("Loaded CasServerLoginUrl parameter: " + this.casServerLoginUrl);  
    51.             setRenew(parseBoolean(getPropertyFromInitParams(filterConfig, "renew", "false")));  
    52.             log.trace("Loaded renew parameter: " + this.renew);  
    53.             setGateway(parseBoolean(getPropertyFromInitParams(filterConfig, "gateway", "false")));  
    54.             log.trace("Loaded gateway parameter: " + this.gateway);  
    55.   
    56.             final String gatewayStorageClass = getPropertyFromInitParams(filterConfig, "gatewayStorageClass", null);  
    57.   
    58.             if (gatewayStorageClass != null) {  
    59.                 try {  
    60.                     this.gatewayStorage = (GatewayResolver) Class.forName(gatewayStorageClass).newInstance();  
    61.                 } catch (final Exception e) {  
    62.                     log.error(e,e);  
    63.                     throw new ServletException(e);  
    64.                 }  
    65.             }  
    66.             //自定义添加代码,用来读取web配置文件中excludes属性值 ---2  
    67.             excludePaths = getPropertyFromInitParams(filterConfig, "excludePaths", null);//filterConfig.getInitParameter("excludePaths");  
    68.             excludePaths = excludePaths.trim();  
    69.         }  
    70.     }  
    71.   
    72.     public void init() {  
    73.         super.init();  
    74.         CommonUtils.assertNotNull(this.casServerLoginUrl, "casServerLoginUrl cannot be null.");  
    75.     }  
    76. // url判断逻辑,这里大家可以根据自己需要来制订规则  
    77.     private boolean isExclude(String uri){  
    78.         boolean isInWhiteList = false;  
    79.         if(excludePaths!=null&& uri!=null){  
    80.             isInWhiteList = uri.matches(excludePaths);  
    81.         }  
    82.         return isInWhiteList;  
    83.     }  
    84.      
    85.       
    86.     public final void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException {  
    87.         final HttpServletRequest request = (HttpServletRequest) servletRequest;  
    88.         final HttpServletResponse response = (HttpServletResponse) servletResponse;  
    89.         final HttpSession session = request.getSession(false);  
    90.         final Assertion assertion = session != null ? (Assertion) session.getAttribute(CONST_CAS_ASSERTION) : null;  
    91.        // 该判断是自定义的对符合条件的url进行通过处理 ---3  
    92.         if(isExclude(request.getRequestURI())){  
    93.             filterChain.doFilter(request, response);  
    94.             return;  
    95.         }  
    96.           
    97.         if (assertion != null) {  
    98.             filterChain.doFilter(request, response);  
    99.             return;  
    100.         }  
    101.   
    102.         final String serviceUrl = constructServiceUrl(request, response);  
    103.         final String ticket = CommonUtils.safeGetParameter(request,getArtifactParameterName());  
    104.         final boolean wasGatewayed = this.gatewayStorage.hasGatewayedAlready(request, serviceUrl);  
    105.   
    106.         if (CommonUtils.isNotBlank(ticket) || wasGatewayed) {  
    107.             filterChain.doFilter(request, response);  
    108.             return;  
    109.         }  
    110.   
    111.         final String modifiedServiceUrl;  
    112.   
    113.         log.debug("no ticket and no assertion found");  
    114.         if (this.gateway) {  
    115.             log.debug("setting gateway attribute in session");  
    116.             modifiedServiceUrl = this.gatewayStorage.storeGatewayInformation(request, serviceUrl);  
    117.         } else {  
    118.             modifiedServiceUrl = serviceUrl;  
    119.         }  
    120.   
    121.         if (log.isDebugEnabled()) {  
    122.             log.debug("Constructed service url: " + modifiedServiceUrl);  
    123.         }  
    124.   
    125.         final String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway);  
    126.   
    127.         if (log.isDebugEnabled()) {  
    128.             log.debug("redirecting to "" + urlToRedirectTo + """);  
    129.         }  
    130.   
    131.         response.sendRedirect(urlToRedirectTo);  
    132.     }  
    133.   
    134.     public final void setRenew(final boolean renew) {  
    135.         this.renew = renew;  
    136.     }  
    137.   
    138.     public final void setGateway(final boolean gateway) {  
    139.         this.gateway = gateway;  
    140.     }  
    141.   
    142.     public final void setCasServerLoginUrl(final String casServerLoginUrl) {  
    143.         this.casServerLoginUrl = casServerLoginUrl;  
    144.     }  
    145.       
    146.     public final void setGatewayStorage(final GatewayResolver gatewayStorage) {  
    147.         this.gatewayStorage = gatewayStorage;  
    148.     }  
    149.       
    150. }  

    说明:上面的例子笔者是想在web中配置不需要认证的url,通过正则表达式来判断,这里相关的规则可以根据自己需要来编写。

    6.到这里就基本完成了,根据自己定义的规则来做测试,大家可以在项目中创建多个jsp或html文件,放在不同目录下(部分设计为通过,部分设计为不通过),然后在浏览器中直接访问这些文件,看是否被拦截而跳到认证见面,通过根据自己定义的规则判断修改是否成功。

  • 相关阅读:
    windows api学习笔记读写其他进程的内存
    WindowsApi学习笔记创建一个简单的窗口
    windows api学习笔记创建进程
    汇编语言基础教程加法指令
    windows api学习笔记使用定时器
    windows api学习笔记多线程
    C#中两个问号的双目运算符
    通过UDP的组播方式收发数据
    windows api学习笔记用临界区对象使线程同步
    工作流学习笔记ifElse活动;从工作流中取出返回值;计算器实例
  • 原文地址:https://www.cnblogs.com/ruiati/p/6306357.html
Copyright © 2011-2022 走看看