CAS客户端的AuthenticationFilter是filter的实现,web容器可以根据它的 <url-pattern> 分发给相应的过滤器链进行处理。但是,这种粒度有时并不能满足我们需要排除拦截一些模块的需求,例如CAS的客户端AuthenticationFilter过滤器是提供登录认证拦截的,有时候某些URL不需要登录就可以被调用,下面我们将会自定义AuthenticationFilter,让它可能排除一些URL。
《单点登录 - 关于CAS客户端的拦截请求和忽略/排除不需要拦截的请求URL的问题》提供了另一种方式。
https://my.oschina.net/thinwonton/blog/1456732
自定义filter后,将提供excludePaths参数进行URL排除,该参数支持正则
<filter>
<filter-name>CASFilter</filter-name>
<filter-class>com.github.thinwonton.cas.filter.AuthenticationFilter</filter-class>
<init-param>
<param-name>casServerLoginUrl</param-name>
<param-value>http://localhost:8080/cas/login</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>http://localhost:8080</param-value>
</init-param>
<init-param>
<param-name>excludePaths</param-name>
<param-value>.*[/,\\]rest[/,\\].*</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CASFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
重点来了
public class AuthenticationFilter extends AbstractCasFilter{
/**
* The URL to the CAS Server login.
*/
private String casServerLoginUrl;
/**
* Whether to send the renew request or not.
*/
private boolean renew = false;
/**
* Whether to send the gateway request or not.
*/
private boolean gateway = false;
/**
* 添加属性,这里用来存放不过滤地址正则表达式,可以根据自己需求定制---1
*/
private String excludePaths;
private GatewayResolver gatewayStorage = new DefaultGatewayResolverImpl();
protected void initInternal(final FilterConfig filterConfig) throws ServletException {
if (!isIgnoreInitConfiguration()) {
super.initInternal(filterConfig);
setCasServerLoginUrl(getPropertyFromInitParams(filterConfig, "casServerLoginUrl", null));
log.trace("Loaded CasServerLoginUrl parameter: " + this.casServerLoginUrl);
setRenew(parseBoolean(getPropertyFromInitParams(filterConfig, "renew", "false")));
log.trace("Loaded renew parameter: " + this.renew);
setGateway(parseBoolean(getPropertyFromInitParams(filterConfig, "gateway", "false")));
log.trace("Loaded gateway parameter: " + this.gateway);
final String gatewayStorageClass = getPropertyFromInitParams(filterConfig, "gatewayStorageClass", null);
if (gatewayStorageClass != null) {
try {
this.gatewayStorage = (GatewayResolver) Class.forName(gatewayStorageClass).newInstance();
} catch (final Exception e) {
log.error(e,e);
throw new ServletException(e);
}
}
//自定义添加代码,用来读取web配置文件中excludes属性值 ---2
excludePaths = getPropertyFromInitParams(filterConfig, "excludePaths", null);//filterConfig.getInitParameter("excludePaths");
excludePaths = excludePaths.trim();
}
}
public void init() {
super.init();
CommonUtils.assertNotNull(this.casServerLoginUrl, "casServerLoginUrl cannot be null.");
}
// url判断逻辑,这里大家可以根据自己需要来制订规则
private boolean isExclude(String uri){
boolean isInWhiteList = false;
if(excludePaths!=null&& uri!=null){
isInWhiteList = uri.matches(excludePaths);
}
return isInWhiteList;
}
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 HttpSession session = request.getSession(false);
final Assertion assertion = session != null ? (Assertion) session.getAttribute(CONST_CAS_ASSERTION) : null;
// 该判断是自定义的对符合条件的url进行通过处理 ---3
if(isExclude(request.getRequestURI())){
filterChain.doFilter(request, response);
return;
}
if (assertion != null) {
filterChain.doFilter(request, response);
return;
}
final String serviceUrl = constructServiceUrl(request, response);
final String ticket = CommonUtils.safeGetParameter(request,getArtifactParameterName());
final boolean wasGatewayed = this.gatewayStorage.hasGatewayedAlready(request, serviceUrl);
if (CommonUtils.isNotBlank(ticket) || wasGatewayed) {
filterChain.doFilter(request, response);
return;
}
final String modifiedServiceUrl;
log.debug("no ticket and no assertion found");
if (this.gateway) {
log.debug("setting gateway attribute in session");
modifiedServiceUrl = this.gatewayStorage.storeGatewayInformation(request, serviceUrl);
} else {
modifiedServiceUrl = serviceUrl;
}
if (log.isDebugEnabled()) {
log.debug("Constructed service url: " + modifiedServiceUrl);
}
final String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway);
if (log.isDebugEnabled()) {
log.debug("redirecting to \"" + urlToRedirectTo + "\"");
}
response.sendRedirect(urlToRedirectTo);
}
public final void setRenew(final boolean renew) {
this.renew = renew;
}
public final void setGateway(final boolean gateway) {
this.gateway = gateway;
}
public final void setCasServerLoginUrl(final String casServerLoginUrl) {
this.casServerLoginUrl = casServerLoginUrl;
}
public final void setGatewayStorage(final GatewayResolver gatewayStorage) {
this.gatewayStorage = gatewayStorage;
}
}