`

Java Web使用Filter过滤器进行统一的访问权限验证

    博客分类:
  • Java
阅读更多
   安全是每一个web程序必须考虑的问题,安全很重要的一部分就是身份验证。我们可以将身份验证写成一个类,然后在每个功能模块实现的时候调用,但是即使你只须一句代码调用身份验证,当你的项目有几百个功能模块的时候,这也是一个不小的工作,说不定有时候还会忘记。

    Filter 技术是 servlet 2.3  新增加的功能,它使用户可以改变一个request 和修改一个 response. Filter  不是一个 servlet, 它不能产生一个 response, 它能够在一个 request 到达 servlet 之前预处理 request, 也可以在离开 servlet 时处理 response. 换种说法 ,filter 其实是一个 ”servlet chaining”(servlet  链 ). 一个 filter  包括 :
  1.  在 servlet 被调用之前截获 ;

  2.  在 servlet 被调用之前检查 servlet request;

  3.  根据需要修改 request 头和 request 数据 ;

  4.  根据需要修改 response 头和 response 数据 ;

  5.  在 servlet 被调用之后截获 .

     具体的在这里不多介绍。用Filter可以做到很多事情,比如常用的SetCharacterEncodingFilter可以统一解决编码问题。总之那些可以统一进行的“预处理”工作就可以用Filter来做。如果我们用Filter来进行统一的身份验证,那样在功能模块代码中就不用管什么权限了。

    大致思路是:定义访问URI及其所需权限,在会话中存储用户所具有的权限,每次访问的时候 根据URI找到所需的权限,然后检查用户是不是满足所有权限要求。如果满足,放行(chain.doFilter(request, response);),如果不满足,拦截(response.sendError(404);)。

实现
AccessIdentity.java
/**
 * 用户身份权限类
 * 
 * @author wenjianwzz
 * 
 */
public class AccessIdentity {
	UserEntity user;
	Date login;
	Date lastActive;
	Date createTime;
	String ip;
	List<String> tips = new ArrayList<String>();
	HashMap<String, Boolean> privilege;
	HashMap<String, Object> attribute = new HashMap<String, Object>();

	public AccessIdentity(String ip) {
		lastActive = createTime = new Date();
		this.ip = ip;
		refreshPrivilege();
	}

	private void refreshPrivilege() {
		if (privilege == null) {
			privilege = new HashMap<String, Boolean>();
		}
		privilege.clear();
		privilege.put("public", true);
		if (user != null) {
			privilege.put("login", true);
			List<String> p = user.getPrivilege();
			if (p != null)
				for (int i = 0; i < p.size(); i++) {
					privilege.put(p.get(i), true);
				}
		}
	}

	public void notifyActive() {
		lastActive = new Date();
	}

	public void notifyLogout() {
		UserManageService.getInstance().unregisterLogin(user.getUsername());
		user.notifyLogout();
		login = null;
		refreshPrivilege();
	}

	synchronized protected void logout() {
		user.notifyLogout();
		login = null;
		refreshPrivilege();
	}

	public void notifyLogin(UserEntity user) {
		if (!user.hasLogin())
			return;
		this.user = user;
		login = new Date();
		UserManageService.getInstance().registerLogin(user.getUsername(), this);
		refreshPrivilege();
	}

	public UserEntity getUser() {
		return user;
	}

	public boolean isHasLogin() {
		if (user == null)
			return false;
		return user.hasLogin();
	}

	public Date getLoginTime() {
		return login;
	}

	public Date getLastActive() {
		return lastActive;
	}

	public Date getCreateTime() {
		return createTime;
	}

	public String getIp() {
		return ip;
	}

	public List<String> getTips() {
		return tips;
	}

	public boolean hasThisPrivilege(String key) {
		Boolean p = privilege.get(key);
		if (p == null)
			return false;
		return p;
	}

	public void setAttribute(String name, Object value) {
		attribute.put(name, value);
	}

	public Object getAttribute(String name) {
		return attribute.get(name);
	}

	public String getTips(int index) {
		return tips.get(index);
	}

	public int getTipsNumber() {
		return tips.size();
	}

	public void addTips(String tips) {
		this.tips.add(tips);
	}

	@Override
	public int hashCode() {
		if (user.getUsername() == null)
			return -1;
		return user.getUsername().hashCode();
	}

}


  Access.java URI-权限类
String path;
	List<List<String>> privilege;

	public Access(String path) {
		this.path = path;
		privilege = new ArrayList<List<String>>();
		privilege.add(new ArrayList<String>());
	}

	public Access addPrivilege(String p, int g) {
		while (g >= privilege.size()) {
			privilege.add(new ArrayList<String>());
		}
		privilege.get(g).add(p);
		return this;
	}

	public Access removePrivilege(String p) {
		privilege.remove(p);
		return this;
	}

	public boolean validate(AccessIdentity id) {
		int j;
		for (int i = 0; i < privilege.size(); i++) {
			for (j = 0; j < privilege.get(i).size(); j++) {
				if (!id.hasThisPrivilege(privilege.get(i).get(j))) {
					break;
				}
			}
			if (j == privilege.get(i).size() && j > 0) {
				return true;
			}
		}
		return false;
	}


  AccessAnalyst.java 权限分析
public class AccessAnalyst {
	static String filepath;

	HashMap<String, Access> map;

	private static AccessAnalyst instance;

	public boolean check(String url,AccessIdentity id) {
		while(url!=null){
			if(map.containsKey(url)){
				return map.get(url).validate(id);
			}
			url=UpUrl(url);
		}
		return false;
	}

	private String UpUrl(String url){
		if(url==null)
			return null;
		if(url.contains("&")){
			return url.split("&")[0];
		}
		if(url.contains("?"))
			return url.split("\\?")[0];
		if(url.contains("/")){
			if("/".equals(url))
				return null;
			String t=url.substring(0,url.lastIndexOf("/"));
			if(t.length()==0)
				return "/";
			return t;
		}
		return null;
	}
	
	public static AccessAnalyst getInstance() {
		if (instance == null) {
			synchronized (AccessAnalyst.class) {
				if (instance == null) {
					instance = new AccessAnalyst();
				}
			}
		}
		return instance;
	}

	public static void init() {
		Config config=ConfigManager.getConfig("wzz.eu.jk.Access");
		String base=ConfigManager.getEnviroment("ContextRoot");
		try {
			filepath = base+config.getValue("path");
		} catch (ConfigMissingException e) {
			System.err.println("Error: AccessAnalyst init config" +
					" missing parameters "+e.getMessage());
		}
	}

	private AccessAnalyst() {
		map = new HashMap<String, Access>();
		init();
		readFile();
	}

	private void readFile() {
		FileMan fm = new FileMan(filepath);
		List<String> lines = fm.readLines();
		fm.close();
		String line;
		String path;
		Access access;
		String[] g;
		String[] gs;
		for (int i = 0; i < lines.size(); i++) {
			line = lines.get(i);
			if(line.startsWith("#"))
				continue;
			gs = line.split(":");
			path = gs[0];
			access = new Access(path);
			gs = gs[1].split("\\|");
			for(int j=0;j<gs.length;j++){
				g=gs[j].split(",");
				for(int k=0;k<g.length;k++){
					access.addPrivilege(g[k], j);
					System.out.println(g[k]+" added to "+path);
				}
			}
			map.put(path, access);
		}
	}
}


  过滤器
public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest r = (HttpServletRequest) request;
		AccessIdentity id = (AccessIdentity) r.getSession().getAttribute("AccessIdentity");
		if (id == null) {
			id = new AccessIdentity(new ClientAnalyst(r).getIpAddr());
			r.getSession().setAttribute("AccessIdentity", id);
		}
		id.notifyActive();
		String query = r.getQueryString();
		String url =r.getRequestURI().replace(r.getContextPath(), "")
				+ ((query != null && query.length() > 0) ? ("?" + query) : "");
		AccessAnalyst aa = AccessAnalyst.getInstance();
		if(aa.check(url, id)){
			chain.doFilter(request, response);
			if(response instanceof HttpServletResponse)
				((HttpServletResponse)response).setHeader("PowerBy", "WZZ.EvolutionUnit.JavaKit");
		}
		else{
			if(response instanceof HttpServletResponse)
				((HttpServletResponse)response).setStatus(404);
		}
	}
3
0
分享到:
评论
1 楼 riplmm 2013-09-02  
不太完整啊

相关推荐

    名为责任链或者拦截器或者过滤器的简单模拟

    以及最早学习到的java web中的javax.servlet.Filter的概念, 都是一种链式的处理流程,这一个环节处理完成,然后处理另一个环节,这样就可以在一个处理本身的之前和之后做一些事情了。 比如说,struts2中Action在...

    单点登录sso-shiro-cas-maven

    最后我们还需要在/spring-node-1/src/main/webapp/WEB-INF/web.xml 文件中配置相关的过滤器拦截全部请求 ``` xml &lt;filter&gt; &lt;filter-name&gt;shiroFilter&lt;/filter-name&gt; &lt;filter-class&gt;org.springframework.web....

    超市管理系统

    在过滤器中,if(url.indexOf("/toLogin") != -1 ||...){ //放行 chain.doFilter(request,response); return; } ②方式2 单独放置登录页面 login.html login.jsp 4.项目周期 1周时间 项目答辩时间...

    Spring Security 中文教程.pdf

    7.4. 使用其他过滤器 —— 基于框架 8. 核心安全过滤器 8.1. FilterSecurityInterceptor 8.2. ExceptionTranslationFilter 8.2.1. AuthenticationEntryPoint 8.2.2. AccessDeniedHandler 8.3. ...

    SpringSecurity 3.0.1.RELEASE.CHM

    7.4. 使用其他过滤器 —— 基于框架 8. 核心安全过滤器 8.1. FilterSecurityInterceptor 8.2. ExceptionTranslationFilter 8.2.1. AuthenticationEntryPoint 8.2.2. AccessDeniedHandler 8.3. ...

    spring security 参考手册中文版

    13.5与其他基于过滤器的框架一起使用 118 13.6高级命名空间配置 118 14.核心安全筛选器 119 14.1 FilterSecurityInterceptor 119 14.2 ExceptionTranslationFilter 121 14.2.1 AuthenticationEntryPoint 122 14.2.2 ...

    Spring Security-3.0.1中文官方文档(翻译版)

    7.4. 使用其他过滤器—— 基于框架 8. 核心安全过滤器 8.1. FilterSecurityInterceptor 8.2. ExceptionTranslationFilter 8.2.1. AuthenticationEntryPoint 8.2.2. AccessDeniedHandler 8.3. ...

    jive.chm

    forum.jsp 4 Jive源代码情景分析-过滤器篇 5 jive每日一步-web.xml 6 全面了解Jive中的ID机制 7 tree树形数据结构 &lt;br&gt; 扩展功能 1 为jive3.x写ColorFilter 2 Jive中的...

    Jive资料集

    &lt;br&gt; 源代码研究 1 Jive中的全局配置 2 Jive源代码情景分析-index.jsp 3 Jive源代码情景分析-forum.jsp 4 Jive源代码情景分析-过滤器篇 5 jive每日一步-web.xml ...

    jfinalpluginsjfinal-dreampie.zip

    14.xss过滤的StringEscapeUtils过滤器实现 public class AttackHandler extends Handler {  @Override  public void handle(String target, HttpServletRequest request, HttpServletResponse ...

    Hadoop实战中文版

    5.2.1 Reduce侧的联结 5.2.2 基于DistributedCache的复制联结 5.2.3 半联结:map侧过滤后在reduce侧联结 5.3 创建一个Bloom filter 5.3.1 Bloom filter做了什么 5.3.2 实现一个Bloom filter 5.3.3 Hadoop 0.20...

    adb1.0.26包含fastboot.exe

    即在 adb shell pm list packages 的基础上可以加一些参数进行过滤查看不同的列表,支持的过滤参数如下: 参数 显示列表 无 所有应用 -f 显示应用关联的 apk 文件 -d 只显示 disabled 的应用 -e 只显示 enabled 的...

    Hadoop实战中文版.PDF

    212.2.2 验证SSH安装 212.2.3 生成SSH密钥对 212.2.4 将公钥分布并登录验证 222.3 运行Hadoop 222.3.1 本地(单机)模式 232.3.2 伪分布模式 242.3.3 全分布模式 252.4 基于Web的集群用户界面 282.5 ...

    测试培训教材

    项目管理员可以使用QC的Excel插件工具来执行需求的批量导入,进行导入之前请先确认已经访问过MQC主页,并安装了QCMSExcelAddin.exe插件。 插件下载地址: http://updates.merc-int.com/qual ... /msexcel/index.html...

Global site tag (gtag.js) - Google Analytics