cas 单点登录实现指定url不过滤

背景:因为系统的庞大,所以将不同模块的系统放在不通的model模块中,这样在开发中可以一定程度上体现解耦的思想,不同模块之间的登录采用的是cas进行单点登录进行管理;但是开发过程中遇到一个问题,就是cas单点登录时,配置的过滤器是过滤所有的url请求的,及所有的请求url必须cas登录后才可以进行访问,但是有些url请求不需要登录的,比如注册请求url,这时我们就需要进行修改cas的过滤机制,但是在网上众多方法都是从新实现cas的AuthenticationFilter过滤器,然后进行重写过滤方法;这种方法较为复杂,还有一种方法cas其实提供了过滤url请求不拦截的配置,详情见下:(思想来源:https://blog.csdn.net/eguid_1/article/details/73611781)
环境:cas-server-webapp-4.1.2(注意版本,cas不同版本之间差距较大)
正文
在配置cas登录的模块下的web.xml文件中找到(不是cas的web.xml)如下配置:

<!-- 该过滤器负责CAS用户的认证工作 -->
	<filter>
		<filter-name>CASFilter</filter-name>
		<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
		<init-param>
			<param-name>casServerLoginUrl</param-name>
			<param-value>http://192.168.4.195:8080/cas/login</param-value>
			<!--这里的server是服务端的IP -->
		</init-param>
		<init-param>
			<param-name>serverName</param-name>
			<param-value>http://192.168.4.195:8080</param-value>
		</init-param>
		<init-param>
			<description>不拦截的请求</description>
			<param-name>ignorePattern</param-name>
			<param-value>/test.html|/views/test/test.html|/lib/*</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>CASFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

上边代码块中关键代码如下:

<init-param>
			<description>不拦截的请求</description>
			<param-name>ignorePattern</param-name>
			<param-value>/test.html|/views/test/test.html|/lib/*</param-value>
		</init-param>

就是配置cas忽略掉的请求,其中,标签中的值可以采用精准匹配忽略掉的请求,也可以使用正则的方式进行过滤忽略的请求,例如

<init-param>
			<description>不拦截的请求</description>
			<param-name>ignorePattern</param-name>
			<param-value>/test*|/views/test/*|/lib/*</param-value>
		</init-param>

配置如上后,需要注意的是,检查下自己配置的 用于将通过CAS认证的用户信息放入当前应用的上下文环境的过滤器,也是需要配置忽略掉的请求的,配置在web.xml文件中,如下:

<filter>
		<filter-name>AutoSetUserFromCASFilter</filter-name>
		<filter-class>com.hsnn.medstgmini.filter.AutoSetUserFromCASFilter</filter-class>
		<init-param>
		<--需要忽略的url,多个采用';'隔开-->
			<param-name>noLoginPaths</param-name>
			<param-value>test.html</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>AutoSetUserFromCASFilter</filter-name>
		<url-pattern>*.html</url-pattern>
	</filter-mapping>

AutoSetUserFromCASFilter过滤器中的配置如下:

package com.hsnn.medstgmini.filter;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;

import javax.servlet.Filter;
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.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.jasig.cas.client.util.AssertionHolder;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.hsnn.medstgmini.Constants;
import com.hsnn.medstgmini.base.sys.model.SysUser;
import com.hsnn.medstgmini.base.sys.service.SysUserManager;

public class AutoSetUserFromCASFilter implements Filter {
	
	private static final Logger log = Logger.getLogger(AutoSetUserFromCASFilter.class);

	private String excludedPages;//web.xml中配置的过滤掉的请求
	private String[] excludedPageArray;//请求截取后的结果

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		
		HttpServletRequest httpRequest = (HttpServletRequest) request;
		HttpServletResponse httpResponse = (HttpServletResponse) response;
		HttpSession session = httpRequest.getSession(true);
		//进行判断当前请求是否在忽略过滤的url的范围内,如果在,则不需要过滤,否则过滤
		if(excludedPageArray!=null){
			for (int i = 0; i < excludedPageArray.length; i++) {
				if(excludedPageArray[i]==null || "".equals(excludedPageArray[i]))continue;
				if(httpRequest.getRequestURI().indexOf(excludedPageArray[i])!=-1 ){
					chain.doFilter(request, response);
					return;
				}
			}

		}

		//实现其他的业务逻辑及判断
	 	// 如session中已经存在用户信息,则不再从Redis Server中加载
 		if (session.getAttribute(Constants.USERINFO) != null) {
 			chain.doFilter(request, response);
 			return;
 		}
		WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(httpRequest.getSession().getServletContext());
		SysUserManager sysUserManager = (SysUserManager) wac.getBean("sysUserManagerImpl");
		// 从CAS中获取登录用户名
		String userName = AssertionHolder.getAssertion().getPrincipal().getName();
		SysUser user = sysUserManager.getUserByUsername(userName);
        user.setLoginIp(request.getRemoteAddr());//获取客户ip地址
        sysUserManager.updateLoginInfo(user);//修改登录iP和登录时间
        log.info("It's ok to get 'SysUser Object' from medstgmini_std.service:" + user);
        session.setAttribute(Constants.USERINFO, user);
		chain.doFilter(request, response);
	}
	
	private void outputErrorInfo(HttpServletRequest httpRequest, HttpServletResponse httpResponse, String errorMsg) throws IOException {
		
		HttpSession session = httpRequest.getSession(true);
		String header = httpRequest.getHeader("x-requested-with");
		String ctx = session.getServletContext().getContextPath();
		
		PrintWriter pw = httpResponse.getWriter();
		pw.write(errorMsg);
		pw.flush();
		pw.close();
		return;
	}
	
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	//初始化时进行读取web.xml中配置的忽略url值,然后根据指定字符进行字符分割
		excludedPages = filterConfig.getInitParameter("noLoginPaths");
		if (StringUtils.isNotEmpty(excludedPages)) {
			excludedPageArray = excludedPages.split(";");
		}
		return;
	}

	@Override
	public void destroy() {
	}
	
	public static byte[] serialize(Object object) {
    	ObjectOutputStream oos = null;
    	ByteArrayOutputStream baos = null;
    	try {
    	//序列化
    	baos = new ByteArrayOutputStream();
    	oos = new ObjectOutputStream(baos);
    	oos.writeObject(object);
    	byte[] bytes = baos.toByteArray();
    	return bytes;
    	} catch (Exception e) {
    	 
    	}
    	return null;
    }
    
    public static Object unserialize(byte[] bytes) {
    	ByteArrayInputStream bais = null;
    	try {
    	//反序列化
    	bais = new ByteArrayInputStream(bytes);
    	ObjectInputStream ois = new ObjectInputStream(bais);
    	return ois.readObject();
    	} catch (Exception e) {
    	 
    	}
    	return null;
    }

}

到这里配置完成,可以实现我们的需求进行忽略掉我们配置的请求了;但是知其然也要知其所以然,下边是跟着cas-client的源码进行分析:
在cas-client的AuthenticationFilter的初始化方法中,有提到ignorePattern (忽略正则),及cas过滤器在初始化的时候已经为我们提供了忽略正则的设置,so我们不需要大费周章的去重写cas的过滤器,而是可以通过查看源码的方式获取更简单更效率的做法;

protected void initInternal(FilterConfig filterConfig) throws ServletException {
        if (!this.isIgnoreInitConfiguration()) {
            super.initInternal(filterConfig);
            this.setCasServerLoginUrl(this.getPropertyFromInitParams(filterConfig, "casServerLoginUrl", (String)null));
            this.logger.trace("Loaded CasServerLoginUrl parameter: {}", this.casServerLoginUrl);
            this.setRenew(this.parseBoolean(this.getPropertyFromInitParams(filterConfig, "renew", "false")));
            this.logger.trace("Loaded renew parameter: {}", this.renew);
            this.setGateway(this.parseBoolean(this.getPropertyFromInitParams(filterConfig, "gateway", "false")));
            this.logger.trace("Loaded gateway parameter: {}", this.gateway);
            String ignorePattern = this.getPropertyFromInitParams(filterConfig, "ignorePattern", (String)null);
            this.logger.trace("Loaded ignorePattern parameter: {}", ignorePattern);
            String ignoreUrlPatternType = this.getPropertyFromInitParams(filterConfig, "ignoreUrlPatternType", "REGEX");
            this.logger.trace("Loaded ignoreUrlPatternType parameter: {}", ignoreUrlPatternType);
            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 var6) {
                        this.logger.error("Could not instantiate class [{}]", ignoreUrlPatternType, var6);
                    }
                }

                if (this.ignoreUrlPatternMatcherStrategyClass != null) {
                    this.ignoreUrlPatternMatcherStrategyClass.setPattern(ignorePattern);
                }
            }

            String gatewayStorageClass = this.getPropertyFromInitParams(filterConfig, "gatewayStorageClass", (String)null);
            if (gatewayStorageClass != null) {
                this.gatewayStorage = (GatewayResolver)ReflectUtils.newInstance(gatewayStorageClass, new Object[0]);
            }

            String authenticationRedirectStrategyClass = this.getPropertyFromInitParams(filterConfig, "authenticationRedirectStrategyClass", (String)null);
            if (authenticationRedirectStrategyClass != null) {
                this.authenticationRedirectStrategy = (AuthenticationRedirectStrategy)ReflectUtils.newInstance(authenticationRedirectStrategyClass, new Object[0]);
            }
        }

    }

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值