urlfilter.java

来自「用的是通过filter过滤来管理权限的方法」· Java 代码 · 共 210 行

JAVA
210
字号
package com.springside.demo.security;

import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
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;

public class UrlFilter implements Filter {
	private FilterConfig filterConfig;

	private FilterChain chain;

	private HttpServletRequest request;

	private HttpServletResponse response;

	public void destroy() {
		this.filterConfig = null;
	}

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

	public void doFilter(ServletRequest servletRequest,
			ServletResponse servletResponse, FilterChain chain)
			throws IOException, ServletException {
		this.chain = chain;
		this.request = (HttpServletRequest) servletRequest;
		this.response = ((HttpServletResponse) servletResponse);

		String url = request.getServletPath();
		if (url == null)
			url = "";

		// 获取session中的loginuser对象
		HttpSession session = request.getSession();
		LoginUser loginuser = (LoginUser) session.getAttribute("loginuser");

		if (baseUrl(url, request)) {
			// 如果是登陆界面等无须权限访问的的公用界面则跳过
			chain.doFilter(request, response);
		} else if (loginuser == null) {
			checkLogin(url);
		} else {
			verifyUrl(url, loginuser);
		}
	}

	private void checkLogin(String url) throws ServletException, IOException {
		// 如果session中获取不到 loginuser 对象,要不就是session 过期了,要不就是还没登陆。所以返回登陆界面
		// 在登陆后记得把 loginuser 对象置于 session中

		if (url.indexOf("/index.jsp") >= 0
				&& "login".equals(request.getParameter("act"))) {
			// 获取request中username,password
			String username = request.getParameter("username");
			String password = request.getParameter("password");
			UserDao userDao = new UserDao();
			if (userDao.authUser(username, password)) {
				LoginUser user = userDao.getUser(username);
				request.getSession().setAttribute("loginuser", user);
				verifyUrl(url,user);
				return;
			}
		}
		response.sendRedirect("login.jsp");
	}

	private void verifyUrl(String url, LoginUser loginuser)
			throws IOException, ServletException {
		// 获取 loginuser 拥有的所有资源串
		Set royurl = loginuser.getResStrings();
		if (royurl != null && royurl.size() > 0 && pass(royurl, url, request.getParameterMap())) {
			chain.doFilter(request, response);
		} else {
			response.setContentType("text/html;charset=GBK");
			response
					.getWriter()
					.println(
							"<div style='margin: 100 auto;text-align: center;"
									+ "font: bold 18px 宋体;color: #0066CC;vertical-align: middle'> Sorry,您没有权限访问该资源!</div>");
		}
	}

	/**
	 * 判断是否是公用界面
	 */
	protected boolean baseUrl(String url, HttpServletRequest request) {
		if (url.indexOf("/login.jsp") >= 0) {
			return true;
		}
		return false;
	}

	/**
	 * 判断该用户是否有权请求该url
	 * 
	 * @param royurl
	 *            user拥有的授权的的url串集合
	 * @param url
	 *            当前请求的url
	 * @param reqmap
	 *            当前request的参数
	 * @return 是否通过该url
	 */
	protected boolean pass(Set royurl, String url, Map reqmap) {
		boolean match = true;
		for (Iterator iter = royurl.iterator(); iter.hasNext();) {
			// 获取资源
			match = true;
			String res_string = (String) iter.next();
			if (res_string.indexOf("*") > 0) {
				res_string = res_string.substring(0, res_string.indexOf("*"));
				if (url.substring(0, res_string.length()).equalsIgnoreCase(
						res_string)) {
					return true; // 增加通配符比较
				}
			}
			// 分割url与参数
			String[] spw = res_string.split("\\?"); // 用"\\?" 转义后即可得到正确的结
			if (!url.equalsIgnoreCase(spw[0])) {
				match = false;
			}
			if (match && spw.length > 1) {
				String[] spa = spw[1].split("\\&"); // 分拆各参数
				for (int j = 0; j < spa.length; j++) {
					String[] spe = spa[j].split("="); // 分拆键与值
					String key = spe[0];
					String value = "";
					if (spe.length > 1) {
						value = spe[1].trim();
					}

					// 轮询
					String[] values = (String[]) reqmap.get(key);
					if (values != null) {
						for (int k = 0; k < values.length; k++) {
							if (value.equalsIgnoreCase(values[k])) {
								match = true;
								break;
							}
							match = false;
						}
						if (!match) {
							break;
						}
					}
				}

			}

			if (match) {
				break;
			}
		}
		return match;
	}

	public static void main(String[] args) {
		UrlFilter filter = new UrlFilter();
		String url = "/baseProd/product.do";

		Map reqmap = new HashMap();
		// 当前请求productline参数是11,12
		reqmap.put("productline", new String[] { "11", "12" });

		String str;
		Set royurl = new HashSet();

		// 和授权的的url根本不同,false
		royurl.add("/user.do?a=1&b=2");
		System.out.println("match false:" + filter.pass(royurl, url, reqmap));
		// 授权的请求参数13,14时 false
		royurl.add("/baseProd/product.do?productline=13&productline=14");
		System.out.println("match false:" + filter.pass(royurl, url, reqmap));
		// 授权的请求参数11,13时 false
		royurl.add("/baseProd/product.do?productline=11&productline=13");
		System.out.println("match false:" + filter.pass(royurl, url, reqmap));

		// 授权的请求参数11时 true
		royurl.add("/baseProd/product.do?productline=11");
		System.out.println("match true:" + filter.pass(royurl, url, reqmap));

		// 参数的不论顺序 true
		royurl.add("/baseProd/product.do?productline=12&productline=11");
		System.out.println("match true:" + filter.pass(royurl, url, reqmap));

		royurl.clear();
		// 支持 "*" 号作通配符 true
		royurl.add("/baseProd/product.do*");
		System.out.println("match ture:" + filter.pass(royurl, url, reqmap));

	}

}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?