安全是每一个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);
}
}
分享到:
相关推荐
本教程将详细讲解如何使用Java Web中的过滤器(Filter)来实现这样的访问控制。过滤器是Servlet API的一部分,它允许我们在请求到达目标资源(如Servlet、JSP页面)之前或之后对请求和响应进行拦截处理。 首先,...
通过实现Filter接口并配置在web.xml中,我们可以对所有请求或特定请求进行拦截,例如进行字符编码转换、权限验证、日志记录等操作。过滤器可以形成一个链,按照定义的顺序执行。 再来看拦截器(Interceptor),这是...
Servlet过滤器是Java Web开发中的一个重要概念,它允许开发者在请求到达Servlet之前或者Servlet响应返回客户端之前进行拦截处理。在本实例中,我们将深入探讨Servlet过滤器(Filter)的使用和实现,以及它在实际应用...
总之,JAVA过滤器作为Java Web开发中的一个重要组成部分,提供了强大的功能和灵活性,可以用于解决多种实际问题,包括但不限于编码处理、权限验证、日志记录、异常处理、数据格式转换和缓存优化等。理解和掌握过滤器...
这个压缩包可能包含了一个示例项目,展示了如何在SpringBoot中配置和使用过滤器或拦截器进行登录验证。你可能需要解压并导入到IDE中,按照提供的说明运行和测试,以便更好地理解和学习这个功能。 通过深入理解这些...
在Java Web开发中,Servlet过滤器(Filter)是不可或缺的一部分,它允许开发者在请求到达Servlet之前或响应离开Servlet之后对其进行处理。Servlet过滤器是按照指定的配置顺序进行调用的,能够实现数据的预处理、后...
在Web后端开发中,Filter过滤器是一种非常重要的技术,它允许开发者在请求到达目标Servlet或者JSP之前以及响应返回给客户端之后进行拦截处理。在本教程中,我们将重点探讨如何利用Filter技术来实现访问量统计,特别...
本篇文章将详细讲解如何通过使用`web.xml`配置文件来实现Filter过滤器,以实现对网站访问量的统计。这种方法是Java Web应用中的经典实践,适用于传统的基于Servlet的项目。 首先,我们需要了解Filter的基本概念。...
在Java的Web开发中,过滤器(Filter)是一种非常实用的技术,它可以在请求到达目标资源(如Servlet或JSP页面)之前或响应离开容器之后进行处理。本文将深入探讨Java中过滤器的几种使用方法及其应用场景,以帮助...
本项目"java web Xss及sql注入过滤器.zip"就是针对这两种威胁提供的一种解决方案,基于流行的Spring Boot 2.0框架进行开发。 XSS 攻击是通过在网页中插入恶意脚本,当其他用户访问该页面时,这些脚本会被执行,从而...
在现代的Java Web应用中,可以通过Java配置或者使用Spring Boot的`@WebFilter`注解来定义过滤器。 8. **过滤器和拦截器的区别**:虽然过滤器和拦截器都能实现类似的逻辑,但过滤器是Servlet规范的一部分,而拦截器...
【Java Filter过滤器详解】 Java Filter是Java Servlet技术的一部分,它允许开发者在Servlet容器中对HTTP请求和响应进行拦截处理,实现数据过滤、权限控制、日志记录等多种功能。Filter的生命周期包括三个主要方法...
Java的过滤器(Filter)是Java Web开发中的一个重要概念,主要应用于Servlet容器中,如Tomcat、Jetty等。过滤器允许开发者在请求被实际处理之前或之后进行拦截,执行预处理或后处理操作,例如权限校验、数据转换、...
在Java Web开发中,过滤器(Filter)是一种非常实用的功能,它可以对用户请求进行预处理或对响应进行后处理。通过配置过滤器,开发者可以在不修改任何现有代码的情况下增强应用程序的功能。本篇文章将围绕“Java...
在JavaWeb开发中,过滤器(Filter)是一个非常重要的组件,它可以实现对HTTP请求和响应进行拦截处理。本文将详细讲解三个使用JavaWeb过滤器的实际案例,帮助开发者深入理解其功能和应用场景。 案例1:分IP统计网站...
Java过滤器(Filter)是Java Web开发中的一个重要概念,它主要应用于Servlet容器中,如Tomcat、Jetty等。过滤器允许我们在数据处理前后插入自定义逻辑,对请求和响应进行拦截、修改或增强。本教程将深入讲解Java过滤...
认证过滤器是Web应用程序中最常见的过滤器之一,主要用于身份验证过程。当用户尝试访问受保护的资源时,这些过滤器会检查用户的凭据,如用户名和密码,确保只有授权用户才能访问相应的资源。认证过滤器通常与Servlet...
在"使用过滤器完成用户登录验证"的场景中,我们将创建一个过滤器类,该类实现了Filter接口并重写了doFilter()方法。在这个方法里,我们可以检查请求中是否有有效的登录信息,例如通过检查请求头中的session或cookie...
过滤器(Filter)是Java Servlet技术中的一种机制,用于在请求到达实际处理请求的Servlet之前进行预处理,或者在响应发送回客户端之后进行后处理。在这个场景下,我们讨论的是如何使用过滤器来实现用户登录验证的...
总结来说,"过滤器--控制不同权限用户访问不同文件夹代码.rar"是一个实用的示例,它展示了如何使用Java Servlet过滤器技术实现精细的权限控制,确保不同权限级别的用户只能访问其被授权的资源。这样的功能对于保护...