自定义 Filter实现登录权限控制(全面)+登录白名单

一、项目中加入自定义filter实现Filter接口

1、写自定义Filter类

public class SessionFilter implements Filter{
    
    
    public FilterConfig config;
    
    private static Map<String, String> authMap = new HashMap<>();

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
	this.config = filterConfig;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
	// 获取request
	HttpServletRequest hrequest = (HttpServletRequest) request;
	// 获取session
	HttpSession session = hrequest.getSession();
	// 能获取response数据,类包装了ServletResponse,可以进行IO操作,返回数据
	HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse) response);
	// 过滤资源后缀参数,已经在web.xml中配置
	String includeStrings = config.getInitParameter("excludeStrings"); 
	// 没有登陆转向页面
	String loginPath = hrequest.getContextPath() + config.getInitParameter("redirectPath");
	// 过滤器是否有效 
	String disabletestfilter = config.getInitParameter("disabletestfilter");
	
	// 过滤器无效,直接跳过
	if (disabletestfilter.toUpperCase().equals("Y")) { 
	    chain.doFilter(request, response);
	    return;
	}
	
	String requestUri = hrequest.getServletPath();
	if ("/".equals(requestUri)) {
	    chain.doFilter(request, response);
	    return;
	}
	
	// 只对指定过滤参数后缀进行过滤,或者请求地址在白名单内
	String[] includeList = includeStrings.split(";");
	if (isContains(requestUri, includeList) || isFilter(requestUri)) {
	    chain.doFilter(request, response);
	    return;
	}
	
	// 判断session中是否有用户登录,如果有过滤
	String user = (String) session.getAttribute("user_session");
	if (user != null) {
	    chain.doFilter(request, response);
	    return;
	}
	// 以上条件都不符合,跳转到登录界面
	wrapper.sendRedirect(loginPath);
	return;
    }

    @Override
    public void destroy() {
	this.config = null;
    }
    
    // 判断请求是否在请求 白名单内
    private static boolean isFilter(String url) {
	if (authMap.isEmpty()) {
	    authMap = cacheProperties("auth");
	    if (authMap.isEmpty()) {
		return true;
	    }
	}
	for (String key : authMap.keySet()) {
	    if (key.contains("**")) {
		key = key.replace("/**", "");
		if (url.startsWith(key)) {
		    return true;
		}
	    } else if (key.equals(url)) {
		return true;
	    }
	}
	return false;
    }
    
    
    public static boolean isContains(String container, String[] regx) {
	for (int i = 0; i < regx.length; i++) {
	    if (container.indexOf(regx[i]) != -1) {
		return true;
	    }
	}
	return false;
    }
    
    // 读取配置文件内容的方法
    public static Map<String, String> cacheProperties(String propName) {
	Map<String, String> map = new HashMap<String, String>();
	ClassPathResource cp = new ClassPathResource(propName + ".properties");
	Properties properties = new Properties();
	try {
	    properties.load(cp.getInputStream());
	} catch (IOException e) {
	    throw new RuntimeException("load "+propName+".properties error!");
	}
	for (Iterator<?> its = properties.keySet().iterator(); its.hasNext();) {
	    String zkey = (String) its.next();
	    map.put(zkey, properties.getProperty(zkey).trim());
	}
	return map;
    }

}

在类中注释的很清楚了,读者如有不懂请留言咨询。

2、白名单配置

#白名单配置,可自行扩展
/common/** = anon
/login = anon
/logon = anno

二、web.xml中配置自定义filter

   <filter>
        <filter-name>SessionFilter</filter-name>
        <filter-class>com.test.filter.SessionFilter</filter-class> <!-- 自定义filter所在包路径 -->
        <init-param>
            <param-name>excludeStrings</param-name>
            <param-value>.css;.js;.jpg;.png</param-value>
        </init-param>
        <init-param>
            <param-name>redirectPath</param-name>
            <param-value>/login</param-value>
        </init-param>
        <init-param>
            <param-name>disabletestfilter</param-name>
            <param-value>N</param-value>
        </init-param>
    </filter>
    
    <filter-mapping>
        <filter-name>SessionFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    

三、测试结果

我们在用户登录时,将用户信息存到session中:

@RequestMapping("logon")
    public String logon(HttpServletRequest request,String userName,String password) {
	if (userName != null) {
	    // 将用户存到session里去
	    HttpSession session = request.getSession();
	    session.setAttribute("user_session", userName);
	    return "index";
	}
	return "login";
    }

1、启动项目跳转到登录页面,当我们不登录直接访问/user/hello这个地址时,我们发现浏览器会自动跳转到登录界面。当我们登录之后,再访问/user/hello时,能跳转到对应的页面。

2、白名单测试,我们把/user/hello加入到我们的白名单中,没有登录访问/user/hello这个地址,我们会发现 直接跳转至相应页面。

至此,自定义过滤器实现完成,过滤器实现的功能如下:

(1)登录权限控制

(2)登录白名单

(3)对一些静态资源文件过滤

欢迎广大读者留言评论。


阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页