cas客户端验证流程

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

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

  
    <filter>   
        <filter-name>CAS Single Sign Out Filterfilter-name>  
        <filter-class>org.jasig.cas.client.session.SingleSignOutFilterfilter-class>
        <init-param>
          <param-name>casServerUrlPrefixparam-name>
          <param-value>http://192.168.20.103:8080/cas-server-webappparam-value>
       init-param>
    filter>   
    <filter-mapping>  
        <filter-name>CAS Single Sign Out Filterfilter-name>  
        <url-pattern>/*url-pattern>  
    filter-mapping>  
    <listener>  
        <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListenerlistener-class>  
    listener>

    <filter>
        <filter-name>Encodingfilter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
        <init-param>
            <param-name>encodingparam-name>
            <param-value>UTF-8param-value>
        init-param>
         <init-param>
            <param-name>forceEncodingparam-name>
            <param-value>trueparam-value>
        init-param>
    filter>
    <filter-mapping>
        <filter-name>Encodingfilter-name>
        <url-pattern>/*url-pattern>
    filter-mapping>

      
    <filter>   
        <filter-name>CAS Filterfilter-name>  
        <filter-class>org.jasig.cas.client.authentication.AuthenticationFilterfilter-class>  
            <init-param>  
                <param-name>casServerLoginUrlparam-name>  
                <param-value>http://192.168.20.103:8080/cas-server-webapp/loginparam-value>  
            init-param>
            <init-param>
                <param-name>serverNameparam-name>  
                <param-value>http://192.168.20.103:8080/zgr-cas-integrateparam-value>  
            init-param>  
    filter>
    <filter-mapping>  
        <filter-name>CAS Filterfilter-name>  
        <url-pattern>/*url-pattern>  
    filter-mapping>   

      
    <filter>    
            <filter-name>CAS Validation Filterfilter-name>  
        <filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilterfilter-class>  
            <init-param>  
                    <param-name>casServerUrlPrefixparam-name>  
                    <param-value>http://192.168.20.103:8080/cas-server-webappparam-value>  
        init-param>  
            <init-param>  
                <param-name>serverNameparam-name>  
                <param-value>http://192.168.20.103:8080/zgr-cas-integrateparam-value>  
        init-param>  
    filter>  
    <filter-mapping>  
            <filter-name>CAS Validation Filterfilter-name>  
         <url-pattern>/*url-pattern>
    filter-mapping>  

      
    <filter>   
        <filter-name>CAS HttpServletRequest Wrapper Filterfilter-name>  
        <filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilterfilter-class>  
    filter>  
    <filter-mapping>  
       <filter-name>CAS HttpServletRequest Wrapper Filterfilter-name>  
        <url-pattern>/*url-pattern>  
    filter-mapping>  

      
    <filter>   
        <filter-name>CAS Assertion Thread Local Filterfilter-name>  
        <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilterfilter-class>  
    filter>   
    <filter-mapping>  
        <filter-name>CAS Assertion Thread Local Filterfilter-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);

    }

你可能感兴趣的:(CAS单点登录)