1、web-xml修改filter:
<listener>
<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>
<!-- CAS -->
<filter>
<filter-name>CAS Single Sign Out Filter</filter-name>
<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
<filter>
<filter-name>CAS Filter</filter-name>
<filter-class>com.cas.client.validation.RemoteAuthenticationFilter</filter-class>
<init-param>
<param-name>localLoginUrl</param-name>
<param-value>http://localhost:8080/c1/login.jsp</param-value>
</init-param>
<init-param>
<param-name>casServerLoginUrl</param-name>
<param-value>https://xuhang-PC:8443/cas/remoteLogin</param-value>
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
<param-value>https://xuhang-PC:8443/cas/serviceValidate</param-value>
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
<param-value>localhost:8080</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Single Sign Out Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- END CAS -->
2、com.cas.client.validation.RemoteAuthenticationFilter代码如下:
com.cas.client.validation.RemoteAuthenticationFilter是修改edu.yale.its.tp.cas.client.filter.CASFilter而来,改动的函数有:
public void init(FilterConfig config) throws ServletException {
casLogin = config.getInitParameter(LOGIN_INIT_PARAM);
casValidate = config.getInitParameter(VALIDATE_INIT_PARAM);
casServiceUrl = config.getInitParameter(SERVICE_INIT_PARAM);
String casAuthorizedProxy = config.getInitParameter(AUTHORIZED_PROXY_INIT_PARAM);
casRenew = Boolean.valueOf(config.getInitParameter(RENEW_INIT_PARAM)).booleanValue();
casServerName = config.getInitParameter(SERVERNAME_INIT_PARAM);
casProxyCallbackUrl = config.getInitParameter(PROXY_CALLBACK_INIT_PARAM);
wrapRequest = Boolean.valueOf(config.getInitParameter(WRAP_REQUESTS_INIT_PARAM)).booleanValue();
casGateway = Boolean.valueOf(config.getInitParameter(GATEWAY_INIT_PARAM)).booleanValue();
if (casGateway && Boolean.valueOf(casRenew).booleanValue()) {
throw new ServletException("gateway and renew cannot both be true in filter configuration");
}
if (casServerName != null && casServiceUrl != null) {
throw new ServletException("serverName and serviceUrl cannot both be set: choose one.");
}
if (casServerName == null && casServiceUrl == null) {
throw new ServletException("one of serverName or serviceUrl must be set.");
}
if (casServiceUrl != null){
if (! (casServiceUrl.startsWith("https://")|| (casServiceUrl.startsWith("http://") ))){
throw new ServletException("service URL must start with http:// or https://; its current value is [" + casServiceUrl + "]");
}
}
if (casValidate == null){
throw new ServletException("validateUrl parameter must be set.");
}
if (! casValidate.startsWith("https://")){
throw new ServletException("validateUrl must start with https://, its current value is [" + casValidate + "]");
}
if (casAuthorizedProxy != null){
// parse and remember authorized proxies
StringTokenizer casProxies =
new StringTokenizer(casAuthorizedProxy);
while (casProxies.hasMoreTokens()) {
String anAuthorizedProxy = casProxies.nextToken();
if (!anAuthorizedProxy.startsWith("https://")){
throw new ServletException("CASFilter initialization parameter for authorized proxies " +
"must be a whitespace delimited list of authorized proxies. " +
"Authorized proxies must be secure (https) addresses. This one wasn't: [" + anAuthorizedProxy + "]");
}
this.authorizedProxies.add(anAuthorizedProxy);
}
}
if (log.isDebugEnabled()){
log.debug(("CASFilter initialized as: [" + toString() + "]"));
}
/*
* RemoteAuthentication 新增部分
*/
casServerLoginUrl = config.getInitParameter("casServerLoginUrl");
log.trace("Loaded CasServerLoginUrl parameter: " + this.casServerLoginUrl);
localLoginUrl = config.getInitParameter("localLoginUrl");
log.trace("Loaded LocalLoginUrl parameter: " + this.localLoginUrl);
}
public void doFilter(ServletRequest request,ServletResponse response,FilterChain filterChain) throws ServletException, IOException {
if (log.isTraceEnabled()){
log.trace("entering doFilter()");
}
// make sure we've got an HTTP request
if (!(request instanceof HttpServletRequest)
|| !(response instanceof HttpServletResponse)) {
log.error("doFilter() called on a request or response that was not an HttpServletRequest or response.");
throw new ServletException("CASFilter protects only HTTP resources");
}
// Is this a request for the proxy callback listener? If so, pass
// it through
if (casProxyCallbackUrl != null
&& casProxyCallbackUrl.endsWith(((HttpServletRequest) request).getRequestURI())
&& request.getParameter("pgtId") != null
&& request.getParameter("pgtIou") != null) {
log.trace("passing through what we hope is CAS's request for proxy ticket receptor.");
filterChain.doFilter(request, response);
return;
}
// Wrap the request if desired
if (wrapRequest) {
log.trace("Wrapping request with CASFilterRequestWrapper.");
request = new CASFilterRequestWrapper((HttpServletRequest) request);
}
HttpSession session = ((HttpServletRequest) request).getSession();
// if our attribute's already present and valid, pass through the filter chain
CASReceipt receipt = (CASReceipt) session.getAttribute(CAS_FILTER_RECEIPT);
if (receipt != null && isReceiptAcceptable(receipt)) {
log.trace("CAS_FILTER_RECEIPT attribute was present and acceptable - passing request through filter..");
filterChain.doFilter(request, response);
return;
}
// otherwise, we need to authenticate via CAS
String ticket = request.getParameter("ticket");
// no ticket? abort request processing and redirect
if (ticket == null || ticket.equals("")) {
log.trace("CAS ticket was not present on request.");
/*
* RemoteAuthentication 新增部分
*/
if (localLoginUrl!=null&&!"".equals(localLoginUrl)){
// 如果访问路径为localLoginUrl且带有validated参数则跳过
URL url = new URL(localLoginUrl);
final boolean isValidatedLocalLoginUrl = ((HttpServletRequest)request).getRequestURI().endsWith(url.getPath()) && CommonUtils.isNotBlank(request.getParameter("validated"));
if (!isValidatedLocalLoginUrl){
if (this.casGateway) {
log.debug("setting gateway attribute in session");
((HttpServletRequest)request).getSession(true).setAttribute(CONST_CAS_GATEWAY, "yes");
}
final String serviceUrl = constructServiceUrl((HttpServletRequest)request, (HttpServletResponse)response);
if (log.isDebugEnabled()) {
log.debug("Constructed service url: " + serviceUrl);
}
String urlToRedirectTo = CommonUtils.constructRedirectUrl(
this.casServerLoginUrl, getServiceParameterName(),
serviceUrl, this.casRenew, this.casGateway);
// 加入localLoginUrl
urlToRedirectTo += (urlToRedirectTo.contains("?") ? "&" : "?") + "loginUrl=" + URLEncoder.encode(localLoginUrl, "utf-8");
if (log.isDebugEnabled()) {
log.debug("redirecting to \"" + urlToRedirectTo + "\"");
}
((HttpServletResponse)response).sendRedirect(urlToRedirectTo);
return;
}else{
// continue processing the request
filterChain.doFilter(request, response);
return;
}
}else{
// did we go through the gateway already?
boolean didGateway = Boolean.valueOf((String) session.getAttribute(CAS_FILTER_GATEWAYED)).booleanValue();
if (casLogin == null) {
//TODO: casLogin should probably be ensured to not be null at filter initialization. -awp9
log.fatal("casLogin was not set, so filter cannot redirect request for authentication.");
throw new ServletException(
"When CASFilter protects pages that do not receive a 'ticket' "
+ "parameter, it needs a edu.yale.its.tp.cas.client.filter.loginUrl "
+ "filter parameter");
}
if (!didGateway) {
log.trace("Did not previously gateway. Setting session attribute to true.");
session.setAttribute(CAS_FILTER_GATEWAYED, "true");
redirectToCAS((HttpServletRequest) request,(HttpServletResponse) response);
// abort chain
return;
} else {
log.trace("Previously gatewayed.");
// if we should be logged in, make sure validation succeeded
if (casGateway || session.getAttribute(CAS_FILTER_USER) != null) {
log.trace("casGateway was true and CAS_FILTER_USER set: passing request along filter chain.");
// continue processing the request
filterChain.doFilter(request, response);
return;
} else {
// unknown state... redirect to CAS
session.setAttribute(CAS_FILTER_GATEWAYED,"true");
redirectToCAS((HttpServletRequest) request,(HttpServletResponse) response);
// abort chain
return;
}
}
}
}
try {
receipt = getAuthenticatedUser((HttpServletRequest) request);
} catch (CASAuthenticationException e) {
log.error(e);
throw new ServletException(e);
}
if (! isReceiptAcceptable(receipt)){
throw new ServletException("Authentication was technically successful but rejected as a matter of policy. [" + receipt + "]");
}
// Store the authenticated user in the session
if (session != null) { // probably unnecessary
session.setAttribute(CAS_FILTER_USER, receipt.getUserName());
session.setAttribute(RemoteAuthenticationFilter.CAS_FILTER_RECEIPT, receipt);
// don't store extra unnecessary session state
session.removeAttribute(CAS_FILTER_GATEWAYED);
}
if (log.isTraceEnabled()){
log.trace("validated ticket to get authenticated receipt [" + receipt + "], now passing request along filter chain.");
}
// continue processing the request
filterChain.doFilter(request, response);
log.trace("returning from doFilter()");
}
3、登录jsp:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>远程CAS客户端登陆页面</title>
<script type="text/javascript">
function getParam(name) {
var queryString = window.location.search;
var param = queryString.substr(1, queryString.length - 1).split("&");
for (var i = 0; i < param.length; i++) {
var keyValue = param[i].split("=");
if (keyValue[0] == name) return keyValue[1];
}
return null;
}
function init() {
// 显示异常信息
var error = getParam("errorMessage");
if (error) {
document.getElementById("errorMessage").innerHTML = decodeURIComponent(error);
}
// 注入service
var service = getParam("service");
if (service)
document.getElementById("service").value = decodeURIComponent(service);
else
document.getElementById("service").value = location.href;
}
</script>
</head>
<body>
<h1>远程CAS客户端登陆页面</h1>
<% if (request.getSession().getAttribute("edu.yale.its.tp.cas.client.filter.user") == null) { %>
<div id="errorMessage"></div>
<form id="myLoginForm" action="https://xuhang-PC:8443/cas/remoteLogin" method="post">
<input type="hidden" id="service" name="service" value="">
<input type="hidden" name="loginUrl" value="http://localhost:8080/c1/login.jsp">
<input type="hidden" name="submit" value="true" />
<input type="hidden" name="lt" value="${loginTicket}" />
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密 码:</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="登陆" /></td>
</tr>
</table>
</form>
<script type="text/javascript">init();</script>
<% } else { %>
<div class="welcome">您好:<%= (String)request.getSession().getAttribute("edu.yale.its.tp.cas.client.filter.user") %></div>
<div id="logout">
<a href="https://xuhang-PC:8443/cas/remoteLogout?service=http://localhost:8080/c1/login.jsp">单点登出</a>
</div>
<% } %>
</body>
</html>