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

    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

/** 
 * 用户身份权限类 
 *  
 */  
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);  
    }  
}  

loveses49 -
共有0个回答