cas客户端验证流程

本文介绍了CAS客户端的验证流程,包括使用版本3.4.1的配置,详细讲解了AuthenticationFilter如何检查用户认证,以及Cas20ProxyReceivingTicketValidationFilter如何验证service ticket的合法性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://github.com/Jasig/java-cas-client

1 客户端配置,我的版本是3.4.1

<!-- CAS Server 通知 CAS Client,删除session,注销登录信息  -->  
    <filter>   
        <filter-name>CAS Single Sign Out Filter</filter-name>  
        <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
        <init-param>
          <param-name>casServerUrlPrefix</param-name>
          <param-value>http://192.168.20.103:8080/cas-server-webapp</param-value>
       </init-param>
    </filter>   
    <filter-mapping>  
        <filter-name>CAS Single Sign Out Filter</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>  
    <listener>  
        <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>  
    </listener>

    <filter>
        <filter-name>Encoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
         <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>Encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- 登录认证,未登录用户导向CAS Server进行认证 -->  
    <filter>   
        <filter-name>CAS Filter</filter-name>  
        <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>  
            <init-param>  
                <param-name>casServerLoginUrl</param-name>  
                <param-value>http://192.168.20.103:8080/cas-server-webapp/login</param-value>  
            </init-param>
            <init-param>
                <param-name>serverName</param-name>  
                <param-value>http://192.168.20.103:8080/zgr-cas-integrate</param-value>  
            </init-param>  
    </filter>
    <filter-mapping>  
        <filter-name>CAS Filter</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>   

    <!-- CAS Client向CAS Server进行ticket验证 -->  
    <filter>    
            <filter-name>CAS Validation Filter</filter-name>  
        <filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>  
            <init-param>  
                    <param-name>casServerUrlPrefix</param-name>  
                    <param-value>http://192.168.20.103:8080/cas-server-webapp</param-value>  
        </init-param>  
            <init-param>  
                <param-name>serverName</param-name>  
                <param-value>http://192.168.20.103:8080/zgr-cas-integrate</param-value>  
        </init-param>  
    </filter>  
    <filter-mapping>  
            <filter-name>CAS Validation Filter</filter-name>  
         <url-pattern>/*</url-pattern>
    </filter-mapping>  

    <!-- 封装request, 支持getUserPrincipal等方法-->  
    <filter>   
        <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>  
        <filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>  
    </filter>  
    <filter-mapping>  
       <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>  

    <!-- 存放Assertion到ThreadLocal中   -->  
    <filter>   
        <filter-name>CAS Assertion Thread Local Filter</filter-name>  
        <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>  
    </filter>   
    <filter-mapping>  
        <filter-name>CAS Assertion Thread Local Filter</filter-name>  
        <url-pattern>/*</url-pattern>
    </filter-mapping>

2 org.jasig.cas.client.authentication.AuthenticationFilter
检查访问的用户是否需要认证。

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;

        if (isRequestUrlExcluded(request)) {
            logger.debug("Request is ignored.");
            filterChain.doFilter(request, response);
            return;
        }

        final HttpSession session = request.getSession(false);
        // 2.1此assertion是在请求经过Cas20ProxyReceivingTicketValidationFilter时被设置,下面会讲到
        final Assertion assertion = session != null ? (Assertion) session.getAttribute(CONST_CAS_ASSERTION) : null;

        if (assertion != null) { // 2.2如果assertion存在,则直接访问资源
            filterChain.doFilter(request, response);
            return;
        }

        final String serviceUrl = constructServiceUrl(request, response); //请求url地址
        final String ticket = retrieveTicketFromRequest(request); // 2.3请求里是否携带ticket,主要检查service ticket(ST)
        final boolean wasGatewayed = this.gateway && this.gatewayStorage.hasGatewayedAlready(request, serviceUrl);

        if (CommonUtils.isNotBlank(ticket) || wasGatewayed) {
            // 2.4如果ST非空,则访问继续(会被下一个filter-Cas20ProxyReceivingTicketValidationFilter特殊处理)
            filterChain.doFilter(request, response);
            return;
        }

        final String modifiedServiceUrl;

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

        logger.debug("Constructed service url: {}", modifiedServiceUrl);

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

        logger.debug("redirecting to \"{}\"", urlToRedirectTo);
        this.authenticationRedirectStrategy.redirect(request, response, urlToRedirectTo); // 2.5用户未经认证,重定向到cas-server登录页面
    }

3.org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter向cas-server验证用户传递的service ticket是否合法

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 String ticket = retrieveTicketFromRequest(request);

        if (CommonUtils.isNotBlank(ticket)) { //3.1 只处理ST非空的情况,与前面2.3一致
            logger.debug("Attempting to validate ticket: {}", ticket);

            try {
                final Assertion assertion = this.ticketValidator.validate(ticket,
                        constructServiceUrl(request, response)); //往cas-server发送请求http://192.168.20.103:8080/cas-server-webapp/serviceValidate?ticket=ST-44-G2dJRpP2dYQnIB14Ydwh-cas01.example.org&service=http%3A%2F%2F192.168.20.103%3A8080%2Fzgr-cas-integrate2%2Fresource%2Fsimple,验证ST的合法性
                logger.debug("Successfully authenticated user: {}", assertion.getPrincipal().getName());
                request.setAttribute(CONST_CAS_ASSERTION, assertion);

                if (this.useSession) {               request.getSession().setAttribute(CONST_CAS_ASSERTION, assertion);//ST验证成功后,把assertion放入session,与前面2.1对应
                }
                onSuccessfulValidation(request, response, assertion);

                if (this.redirectAfterValidation) {
                    logger.debug("Redirecting after successful ticket validation.");
                    response.sendRedirect(constructServiceUrl(request, response));
                    return;
                }
            } catch (final TicketValidationException e) {
                //如果验证失败,则抛出异常。失败的原因一般是ST超时而失效
                logger.debug(e.getMessage(), e);
                onFailedValidation(request, response);
                if (this.exceptionOnValidationFailure) {
                    throw new ServletException(e);
                }

                response.sendError(HttpServletResponse.SC_FORBIDDEN, e.getMessage());

                return;
            }
        }

        filterChain.doFilter(request, response);

    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值