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);
}