在cas客户端,我们有些请求的接口可能是对外开放的公共接口,可能还有部分静态资源,不想通过cas进行拦截控制,需要直接暴露在外,然而,我们该如何去处理这些问题?:
打开cas客户端的web.xml文件,找到:
我们点进org.jasig.cas.client.authentication.AuthenticationFilter类,可以看到其拦截源码:
在源码中,我们可以看到它是如何跳过继续执行的:
现我们来重新创建一个自定义的过滤器(AuthenticationFilter.java),让它也继承org.jasig.cas.client.util.AbstractCasFilter类,把AuthenticationFilter.class中的源码拷贝进来,在web.xml了拦截配置中添加:
<init-param>
<param-name>ignoreInterface</param-name>
<param-value>/webroot/js/,/webroot/css/,/webroot/img/,/cars/list.do,/alarm/info.do,/logout.do</param-value>
</init-param>
修改原来的过滤类org.jasig.cas.client.authentication.AuthenticationFilter,变成com.abc.ion.realm.AuthenticationFilter。
后如图:
AuthenticationFilter 类中添加一个自定义数组属性:
后续用于存放解析了xml中不拦截的url,然后我们在initInternal方法中添加代码来获取web.xml中不拦截的属性配置:
之后,我们找到doFilter方法,在该方法中去解析并处理我们所自定义的url放行策略:
修改过的代码都很简单,就不过多解释了。
最终的AuthenticationFilter类文件如下,可进行参考:
package com.abc.ion.realm;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.jasig.cas.client.Protocol;
import org.jasig.cas.client.authentication.AuthenticationRedirectStrategy;
import org.jasig.cas.client.authentication.ContainsPatternUrlPatternMatcherStrategy;
import org.jasig.cas.client.authentication.DefaultAuthenticationRedirectStrategy;
import org.jasig.cas.client.authentication.DefaultGatewayResolverImpl;
import org.jasig.cas.client.authentication.ExactUrlPatternMatcherStrategy;
import org.jasig.cas.client.authentication.GatewayResolver;
import org.jasig.cas.client.authentication.RegexUrlPatternMatcherStrategy;
import org.jasig.cas.client.authentication.UrlPatternMatcherStrategy;
import org.jasig.cas.client.configuration.ConfigurationKey;
import org.jasig.cas.client.configuration.ConfigurationKeys;
import org.jasig.cas.client.util.AbstractCasFilter;
import org.jasig.cas.client.util.CommonUtils;
import org.jasig.cas.client.util.ReflectUtils;
import org.jasig.cas.client.validation.Assertion;
/**
* CAS自定义权限拦截控制(放行不需要拦截的接口,配置在web.xml中)
*
* @author DaiHaijiao
*/
public class AuthenticationFilter extends AbstractCasFilter {
private String casServerLoginUrl;
private boolean renew = false;
private boolean gateway = false;
private String[] ignoreInterfaces = null;
private GatewayResolver gatewayStorage = new DefaultGatewayResolverImpl();
private AuthenticationRedirectStrategy authenticationRedirectStrategy = new DefaultAuthenticationRedirectStrategy();
private UrlPatternMatcherStrategy ignoreUrlPatternMatcherStrategyClass = null;
private static final Map<String, Class<? extends UrlPatternMatcherStrategy>> PATTERN_MATCHER_TYPES = new HashMap<String, Class<? extends UrlPatternMatcherStrategy>>();
static {
PATTERN_MATCHER_TYPES.put("CONTAINS", ContainsPatternUrlPatternMatcherStrategy.class);
PATTERN_MATCHER_TYPES.put("REGEX", RegexUrlPatternMatcherStrategy.class);
PATTERN_MATCHER_TYPES.put("EXACT", ExactUrlPatternMatcherStrategy.class);
}
public AuthenticationFilter() {
this(Protocol.CAS2);
}
protected AuthenticationFilter(Protocol protocol) {
super(protocol);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
protected void initInternal(FilterConfig filterConfig) throws ServletException {
if (!isIgnoreInitConfiguration()) {
super.initInternal(filterConfig);
setCasServerLoginUrl(getString(ConfigurationKeys.CAS_SERVER_LOGIN_URL));
setRenew(getBoolean(ConfigurationKeys.RENEW));
setGateway(getBoolean(ConfigurationKeys.GATEWAY));
String ignorePattern = getString(ConfigurationKeys.IGNORE_PATTERN);
String ignoreUrlPatternType = getString(ConfigurationKeys.IGNORE_URL_PATTERN_TYPE);
if (ignorePattern != null) {
Class<? extends UrlPatternMatcherStrategy> ignoreUrlMatcherClass = (Class) PATTERN_MATCHER_TYPES.get(ignoreUrlPatternType);
if (ignoreUrlMatcherClass != null) {
this.ignoreUrlPatternMatcherStrategyClass = ((UrlPatternMatcherStrategy) ReflectUtils.newInstance(ignoreUrlMatcherClass.getName(), new Object[0]));
} else {
try {
this.logger.trace("Assuming {} is a qualified class name...", ignoreUrlPatternType);
this.ignoreUrlPatternMatcherStrategyClass = ((UrlPatternMatcherStrategy) ReflectUtils.newInstance(ignoreUrlPatternType, new Object[0]));
} catch (IllegalArgumentException e) {
this.logger.error("Could not instantiate class [{}]", ignoreUrlPatternType, e);
}
}
if (this.ignoreUrlPatternMatcherStrategyClass != null) {
this.ignoreUrlPatternMatcherStrategyClass.setPattern(ignorePattern);
}
}
ConfigurationKey<String> ignoreInterface = new ConfigurationKey("ignoreInterface", null);
ignoreInterfaces = getString(ignoreInterface).split(",");
Class<? extends GatewayResolver> gatewayStorageClass = getClass(ConfigurationKeys.GATEWAY_STORAGE_CLASS);
if (gatewayStorageClass != null) {
setGatewayStorage((GatewayResolver) ReflectUtils.newInstance(gatewayStorageClass, new Object[0]));
}
Class<? extends AuthenticationRedirectStrategy> authenticationRedirectStrategyClass = getClass(ConfigurationKeys.AUTHENTICATION_REDIRECT_STRATEGY_CLASS);
if (authenticationRedirectStrategyClass != null) {
this.authenticationRedirectStrategy = ((AuthenticationRedirectStrategy) ReflectUtils.newInstance(authenticationRedirectStrategyClass, new Object[0]));
}
}
}
public void init() {
super.init();
CommonUtils.assertNotNull(this.casServerLoginUrl, "casServerLoginUrl cannot be null.");
}
public final void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String uri = request.getRequestURI();
boolean b = false;
for (String interfaceName : ignoreInterfaces) {
if (uri.indexOf(interfaceName) != -1) {
b = true;
break;
}
}
if (b) {
filterChain.doFilter(request, response);
return;
}
if (isRequestUrlExcluded(request)) {
this.logger.debug("Request is ignored.");
filterChain.doFilter(request, response);
return;
}
HttpSession session = request.getSession(false);
Assertion assertion = session != null ? (Assertion) session.getAttribute("_const_cas_assertion_") : null;
if (assertion != null) {
filterChain.doFilter(request, response);
return;
}
String serviceUrl = constructServiceUrl(request, response);
String ticket = retrieveTicketFromRequest(request);
boolean wasGatewayed = (this.gateway) && (this.gatewayStorage.hasGatewayedAlready(request, serviceUrl));
if ((CommonUtils.isNotBlank(ticket)) || (wasGatewayed)) {
filterChain.doFilter(request, response);
return;
}
this.logger.debug("no ticket and no assertion found");
String modifiedServiceUrl;
if (this.gateway) {
this.logger.debug("setting gateway attribute in session");
modifiedServiceUrl = this.gatewayStorage.storeGatewayInformation(request, serviceUrl);
} else {
modifiedServiceUrl = serviceUrl;
}
this.logger.debug("Constructed service url: {}", modifiedServiceUrl);
String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, getProtocol().getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway);
this.logger.debug("redirecting to \"{}\"", urlToRedirectTo);
this.authenticationRedirectStrategy.redirect(request, response, urlToRedirectTo);
}
public final void setRenew(boolean renew) {
this.renew = renew;
}
public final void setGateway(boolean gateway) {
this.gateway = gateway;
}
public final void setCasServerLoginUrl(String casServerLoginUrl) {
this.casServerLoginUrl = casServerLoginUrl;
}
public final void setGatewayStorage(GatewayResolver gatewayStorage) {
this.gatewayStorage = gatewayStorage;
}
private boolean isRequestUrlExcluded(HttpServletRequest request) {
if (this.ignoreUrlPatternMatcherStrategyClass == null) {
return false;
}
StringBuffer urlBuffer = request.getRequestURL();
if (request.getQueryString() != null) {
urlBuffer.append("?").append(request.getQueryString());
}
String requestUri = urlBuffer.toString();
return this.ignoreUrlPatternMatcherStrategyClass.matches(requestUri);
}
}