主要思路:浏览器访问CAS服务器登录,拿到凭证给后端,后端用此凭证到CAS服务器验证登录并拿到用户信息,之后基于该凭证维持用户的登录状态。
主要流程:
1.浏览器访问后端需认证登录地址(不带ticket)
2.后端向浏览器发送重定向信息到cas服务端(参数带跳转CAS服务器的地址)
3.浏览器访问CAS服务端验证登录(参数带跳转后端的地址)
4.CAS服务器向浏览器发送重定向信息到后端的地址(带ticket)
5.后端用此ticket访问CAS服务端验证用户是否登录。
步骤2后端源码片段
org.jasig.cas.client.authentication.AuthenticationFilter#doFilter
这个AuthenticationFilter过滤器专门用户浏览器第一次访问时的跳转,专门检测ticket是否存在。不存在就重定向到cas服务器,存在就不处理
第一次访问后端认证地址没有ticket,重定地址到登录cas服务器
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);
final Assertion assertion = session != null ? (Assertion) session.getAttribute(CONST_CAS_ASSERTION) : null;
if (assertion != null) {
filterChain.doFilter(request, response);
return;
}
final String serviceUrl = constructServiceUrl(request, response);
final String ticket = retrieveTicketFromRequest(request);
final boolean wasGatewayed = this.gateway && this.gatewayStorage.hasGatewayedAlready(request, serviceUrl);
if (CommonUtils.isNotBlank(ticket) || wasGatewayed) {
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);
}
步骤5后端源码片段
org.jasig.cas.client.validation.AbstractTicketValidationFilter#doFilter
validation.AbstractTicket类是后端 通过前端带过来的ticket请求cas服务器,认证有效性。
底层调用HttlsURLConnectionFactory。需要实现AbstractTicket自定义认证方式
public final void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse,
final FilterChain filterChain) throws IOException, ServletException {
if (!preFilter(servletRequest, servletResponse, filterChain)) {
return;
}
final HttpServletRequest request = (HttpServletRequest) servletRequest;
final HttpServletResponse response = (HttpServletResponse) servletResponse;
final String ticket = retrieveTicketFromRequest(request);
if (CommonUtils.isNotBlank(ticket)) {
logger.debug("Attempting to validate ticket: {}", ticket);
try {
final Assertion assertion = this.ticketValidator.validate(ticket,
constructServiceUrl(request, response));
logger.debug("Successfully authenticated user: {}", assertion.getPrincipal().getName());
request.setAttribute(CONST_CAS_ASSERTION, assertion);
if (this.useSession) {
request.getSession().setAttribute(CONST_CAS_ASSERTION, assertion);
}
onSuccessfulValidation(request, response, assertion);
if (this.redirectAfterValidation) {
logger.debug("Redirecting after successful ticket validation.");
response.sendRedirect(constructServiceUrl(request, response));
return;
}
} catch (final TicketValidationException e) {
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服务器跳转地址,后端地址

被折叠的 条评论
为什么被折叠?



