`

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权限访问过滤器

    本教程将详细讲解如何使用Java Web中的过滤器(Filter)来实现这样的访问控制。过滤器是Servlet API的一部分,它允许我们在请求到达目标资源(如Servlet、JSP页面)之前或之后对请求和响应进行拦截处理。 首先,...

    java-web -- servlet 拦截器 过滤器使用

    通过实现Filter接口并配置在web.xml中,我们可以对所有请求或特定请求进行拦截,例如进行字符编码转换、权限验证、日志记录等操作。过滤器可以形成一个链,按照定义的顺序执行。 再来看拦截器(Interceptor),这是...

    servlet过滤器技术实例,

    Servlet过滤器是Java Web开发中的一个重要概念,它允许开发者在请求到达Servlet之前或者Servlet响应返回客户端之前进行拦截处理。在本实例中,我们将深入探讨Servlet过滤器(Filter)的使用和实现,以及它在实际应用...

    JAVA过滤器标准代码

    总之,JAVA过滤器作为Java Web开发中的一个重要组成部分,提供了强大的功能和灵活性,可以用于解决多种实际问题,包括但不限于编码处理、权限验证、日志记录、异常处理、数据格式转换和缓存优化等。理解和掌握过滤器...

    Java SpringBoot实现的过滤器(和拦截器)控制登录页面跳转

    这个压缩包可能包含了一个示例项目,展示了如何在SpringBoot中配置和使用过滤器或拦截器进行登录验证。你可能需要解压并导入到IDE中,按照提供的说明运行和测试,以便更好地理解和学习这个功能。 通过深入理解这些...

    JAVA WEB中的Servlet过滤器

    在Java Web开发中,Servlet过滤器(Filter)是不可或缺的一部分,它允许开发者在请求到达Servlet之前或响应离开Servlet之后对其进行处理。Servlet过滤器是按照指定的配置顺序进行调用的,能够实现数据的预处理、后...

    Web后端开发-使用Filter过滤器技术,实现访问量统计

    在Web后端开发中,Filter过滤器是一种非常重要的技术,它允许开发者在请求到达目标Servlet或者JSP之前以及响应返回给客户端之后进行拦截处理。在本教程中,我们将重点探讨如何利用Filter技术来实现访问量统计,特别...

    Web后端开发-使用Filter过滤器技术,实现访问量统计-方法二使用web.xml配置的方式

    本篇文章将详细讲解如何通过使用`web.xml`配置文件来实现Filter过滤器,以实现对网站访问量的统计。这种方法是Java Web应用中的经典实践,适用于传统的基于Servlet的项目。 首先,我们需要了解Filter的基本概念。...

    filter的使用 java 过滤器的几种使用方法

    在Java的Web开发中,过滤器(Filter)是一种非常实用的技术,它可以在请求到达目标资源(如Servlet或JSP页面)之前或响应离开容器之后进行处理。本文将深入探讨Java中过滤器的几种使用方法及其应用场景,以帮助...

    java web Xss及sql注入过滤器.zip

    本项目"java web Xss及sql注入过滤器.zip"就是针对这两种威胁提供的一种解决方案,基于流行的Spring Boot 2.0框架进行开发。 XSS 攻击是通过在网页中插入恶意脚本,当其他用户访问该页面时,这些脚本会被执行,从而...

    accp java过滤器 PPT

    在现代的Java Web应用中,可以通过Java配置或者使用Spring Boot的`@WebFilter`注解来定义过滤器。 8. **过滤器和拦截器的区别**:虽然过滤器和拦截器都能实现类似的逻辑,但过滤器是Servlet规范的一部分,而拦截器...

    java filter过滤器

    【Java Filter过滤器详解】 Java Filter是Java Servlet技术的一部分,它允许开发者在Servlet容器中对HTTP请求和响应进行拦截处理,实现数据过滤、权限控制、日志记录等多种功能。Filter的生命周期包括三个主要方法...

    java的过滤器

    Java的过滤器(Filter)是Java Web开发中的一个重要概念,主要应用于Servlet容器中,如Tomcat、Jetty等。过滤器允许开发者在请求被实际处理之前或之后进行拦截,执行预处理或后处理操作,例如权限校验、数据转换、...

    Java自定义过滤器

    在Java Web开发中,过滤器(Filter)是一种非常实用的功能,它可以对用户请求进行预处理或对响应进行后处理。通过配置过滤器,开发者可以在不修改任何现有代码的情况下增强应用程序的功能。本篇文章将围绕“Java...

    JavaWeb中过滤器的三个小案例

    在JavaWeb开发中,过滤器(Filter)是一个非常重要的组件,它可以实现对HTTP请求和响应进行拦截处理。本文将详细讲解三个使用JavaWeb过滤器的实际案例,帮助开发者深入理解其功能和应用场景。 案例1:分IP统计网站...

    JAVA过滤器及原理

    Java过滤器(Filter)是Java Web开发中的一个重要概念,它主要应用于Servlet容器中,如Tomcat、Jetty等。过滤器允许我们在数据处理前后插入自定义逻辑,对请求和响应进行拦截、修改或增强。本教程将深入讲解Java过滤...

    java一些 常用 的过滤 器

    认证过滤器是Web应用程序中最常见的过滤器之一,主要用于身份验证过程。当用户尝试访问受保护的资源时,这些过滤器会检查用户的凭据,如用户名和密码,确保只有授权用户才能访问相应的资源。认证过滤器通常与Servlet...

    使用过滤器完成用户登录验证

    在"使用过滤器完成用户登录验证"的场景中,我们将创建一个过滤器类,该类实现了Filter接口并重写了doFilter()方法。在这个方法里,我们可以检查请求中是否有有效的登录信息,例如通过检查请求头中的session或cookie...

    使用过滤器实现判断用户是否登录验证.

    过滤器(Filter)是Java Servlet技术中的一种机制,用于在请求到达实际处理请求的Servlet之前进行预处理,或者在响应发送回客户端之后进行后处理。在这个场景下,我们讨论的是如何使用过滤器来实现用户登录验证的...

    过滤器--控制不同权限用户访问不同文件夹代码.rar

    总结来说,"过滤器--控制不同权限用户访问不同文件夹代码.rar"是一个实用的示例,它展示了如何使用Java Servlet过滤器技术实现精细的权限控制,确保不同权限级别的用户只能访问其被授权的资源。这样的功能对于保护...

Global site tag (gtag.js) - Google Analytics