应用4:利用Filter限制用户浏览权限

Posted afangfang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了应用4:利用Filter限制用户浏览权限相关的知识,希望对你有一定的参考价值。

1. 使用 Filter 完成一个简单的权限模型:

1). 需求:

     ①. 管理权限

           > 查看某人的权限

           > 修改某人的权限

     ②. 对访问进行权限控制: 有权限则可以访问, 否则提示: 没有对应的权限, 请 返回

2). 实现:

     ①. 对访问进行权限控制:

          > 使用 Filter 进行权限的过滤: 检验用户是否有权限, 若有, 则直接响应目标页面; 若没有重定向到 403.jsp

 403.jsp

<body>
    <h4>
        没有对应的权限, 
        请 <a href="${pageContext.request.contextPath }/articles.jsp">返回</a>
    </h4>
</body>

     ②. 使用 Filter 如何进行过滤:

          - 获取 servletPath, 类似于 /app_3/article-1.jsp

          - 在用户已经登录(可使用 用户是否登录 的过滤器)的情况下, 获取用户信息. session.getAttribute("user")

          - 再获取用户所具有的权限的信息: List<Authority>

          - 检验用户是否有请求 servletPath 的权限: 可以思考除了遍历以外, 有没有更好的实现方式

          - 若有权限则: 响应

          - 若没有权限: 重定向到 403.jsp

     ③.others:

          - 用户若登录, 需要把用户信息(User 对象)放入到 HttpSession 中.

          - 在检验权限之前, 需要判断用户是否已经登录.

3). 管理权限:

      ①. 封装权限信息: Authority
            Authority{
                    //显示到页面上的权限的名字

                    private String displayName;

                    //权限对应的 URL 地址: 已权限对应着一个 URL, 例如 Article_1 -> /app_4/article1.jsp

                    private String url;
           }

      ②. 封装用户信息: User

            User{

                 private String username;

                 private List<Autority> authorities;
                 //...
            }

      ③创建一个 UserDao:

          User get(String username);

          void update(String username, List<Autority>);
4). 页面

   authority-manager.jsp:

   有一个 text 文本框, 供输入 username, 提交后, 使用 checkbox 显示当前用户所有的权限的信息.
5). Servlet

     authority-manager.jsp 提交表单后 get 方法: 获取表单的请求参数: username,

     再根据 username 获取 User 信息. 把 user 放入到request 中, 转发到 authority-manager.jsp.

     authority-manager.jsp 修改权限的表单提交后 update 方法: 获取请求参数: username, authory(多选);

     把选项封装为 List; 调用UserDao 的 update() 方法实现权限的修改; 重定向到 authority-manager.jsp

目录

技术图片

权限管理部分代码实现

Authority.java

package com.aff.javaweb;

public class Authority {

    //显示到页面上的权限的名字
    private String displayName;
    
    //权限对应的 URL 地址: 已权限对应着一个 URL, 例如 Article-1 -> /article-1.jsp
    private String url;

    public String getDisplayName() {
        return displayName;
    }

    public void setDisplayName(String displayName) {
        this.displayName = displayName;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public Authority(String displayName, String url) {
        super();
        this.displayName = displayName;
        this.url = url;
    }

    public Authority() {
        // TODO Auto-generated constructor stub
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((url == null) ? 0 : url.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Authority other = (Authority) obj;
        if (url == null) {
            if (other.url != null)
                return false;
        } else if (!url.equals(other.url))
            return false;
        return true;
    }
    
}

 

User.java

package com.aff.javaweb;

import java.util.List;

public class User {
    private String username;
    private List<Authority> authorities;

    public User() {
    }

    public User(String username, List<Authority> authorities) {
        super();
        this.username = username;
        this.authorities = authorities;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public List<Authority> getAuthorities() {
        return authorities;
    }

    public void setAuthorities(List<Authority> authorities) {
        this.authorities = authorities;
    }

}

 

UserDao.java

package com.aff.javaweb;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class UserDao {
    private static Map<String, User> users;
    private static List<Authority> authorities = null;
    static {
        authorities = new ArrayList<>();
        authorities.add(new Authority("Article-1", "/article-1.jsp"));
        authorities.add(new Authority("Article-2", "/article-2.jsp"));
        authorities.add(new Authority("Article-3", "/article-3.jsp"));
        authorities.add(new Authority("Article-4", "/article-4.jsp"));

        users = new HashMap<String, User>();
        User user1 = new User("AAA", authorities.subList(0, 2));
        users.put("AAA", user1);

        user1 = new User("BBB", authorities.subList(2, 4));
        users.put("BBB", user1);
    }

    User get(String username) {
        return users.get(username);
    }

    void update(String username, List<Authority> authorities) {
        users.get(username).setAuthorities(authorities);
    }

    public List<Authority> getAuthorities() {
        return authorities;
    }

    public List<Authority> getAuthorities(String[] urls) {
        List<Authority> authorities2 = new ArrayList<>();
        for (Authority authority : authorities) {
            if (urls != null) {
                for (String url : urls) {
                    if (url.equals(authority.getUrl())) {
                        authorities2.add(authority);

                    }
                }
            }
        }
        return authorities2;
    }

}

 

authority-manager.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <center>
        <br><br>
        <form action="AuthorityServlet?method=getAuthorities" method="post">
            name:<input type="text" name="username" /> <input type="submit"
                value="Submit" />
        </form>
        
        <c:if test="${requestScope.user != null }">
            <br><br>
            
            ${requestScope.user.username } 的权限是:
            <br><br>
            
            <form action="AuthorityServlet?method=updateAuthority"   method="post">
            
            <input type="hidden" name="username" value="${requestScope.user.username }">
            
            <c:forEach items="${authorities }"  var="auth">
            <c:set var="flag" value="false"></c:set>
                    <c:forEach items="${user.authorities }" var="ua">
                           <c:if test="${ua.url==auth.url }">
                                    <c:set var="flag" value="true"></c:set>
                           </c:if>
                    
                    </c:forEach>
            
                    <c:if test="${flag == true }">
                            <input type="checkbox" name="authority" value="${auth.url}" checked="checked"/>${auth.displayName }
                    </c:if>
                    <c:if test="${flag == false }">
                            <input type="checkbox" name="authority" value="${auth.url}" />${auth.displayName }
                    </c:if>
                    <br><br>
            </c:forEach>
            
            <input type="submit" value="Update"/>
            
            </form>
            
        </c:if>
        
    </center>
</body>
</html>

 

AuthorityServlet.java

package com.aff.javaweb;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class AuthorityServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String methodName = request.getParameter("method");
        try {
            Method method = getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
            method.invoke(this, request, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private UserDao userDao = new UserDao();

    public void getAuthorities(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String username = request.getParameter("username");
        User user = userDao.get(username);

        request.setAttribute("user", user);
        request.setAttribute("authorities", userDao.getAuthorities());
        request.getRequestDispatcher("/authority-manager.jsp").forward(request, response);
    }

    public void updateAuthority(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String username = request.getParameter("username");
        String[] authorities = request.getParameterValues("authority");
        List<Authority> authorityList = userDao.getAuthorities(authorities);

        userDao.update(username, authorityList);
        response.sendRedirect(request.getContextPath() + "/authority-manager.jsp");
    }
}

 

权限过滤代码实现

 article-1.jsp

<body>
    Article 111
</body>

 

article-2.jsp

<body>
    Article 222
</body>

 

article-3.jsp

<body>
    Article 333
</

 

article-4.jsp

<body>
    Article 444
</body>

 

articles.jsp

<body>
    <a href="article-1.jsp">Article111 Page</a>
    <br /><br />
    
    <a href="article-2.jsp">Article222 Page</a>
    <br /><br />
    
    <a href="article-3.jsp">Article333 Page</a>
    <br /><br />
    
    <a href="article-4.jsp">Article444 Page</a>
    <br /><br />
    
    <a href="LoginServlet?method=logout">Logout...</a>
</body>

 

login.jsp

<body>
    <form action="LoginServlet?method=login" method="post">
        name: <input type="text" name="name" />
        <input type="submit" value="Submit" />
    </form>
</body>

 

logout.jsp

<body>
    Bye!
    
    <br><br>
    <a href="login.jsp">Login</a>
    <% 
        session.invalidate();
    %>
</body>

 

LoginServlet.java

package com.aff.javaweb;

import java.io.IOException;
import java.lang.reflect.Method;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) {
        String methodName = request.getParameter("method");
        try {
            Method method = getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
            method.invoke(this, request, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private UserDao userDao = new UserDao();

    public void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 获取name
        String name = request.getParameter("name");
        // 调用UserDao 获取用户信息, 把用户信息放入到HttpSession中
        User user = userDao.get(name);
        request.getSession().setAttribute("user", user);
        // 重定向到articles.jsp
        response.sendRedirect(request.getContextPath() + "/articles.jsp");
    }

    public void logout(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 获取HttpSession
        // 使HttpSession失效
        request.getSession().invalidate();

        // 重定向到 /login.jsp
        response.sendRedirect(request.getContextPath() + "/login.jsp");
    }

}

 

AuthorityFilter.java

package com.aff.javaweb;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebFilter("*.jsp")
public class AuthorityFilter extends HttpFilter {

    @Override
    public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // 获取 servletPath
        String servletPath = request.getServletPath();
        // 不需要拦截的url
        List<String> uncheckedUrls = Arrays.asList("/403.jsp", "/articles.jsp", "/authority-manager.jsp", "/login.jsp",
                "/logout.jsp");
        if (uncheckedUrls.contains(servletPath)) {
            chain.doFilter(request, response);
            return;
        }

        // 在用户已经登陆(可使用 用户是否登陆的 过滤器)的情况下, 获取用户信息, session.getAttribute("user")
        User user = (User) request.getSession().getAttribute("user");
        if (user == null) {
            response.sendRedirect(request.getContextPath() + "/login.jsp");
            return;
        }

        // 再获取用户所具有的权限的信息:List<Authority>
        List<Authority> authorities = user.getAuthorities();

        // 检验用户是否请求servletPath 的权限: 可以思考除了遍历以外,有没有更好的实现方法
        Authority authority = new Authority(null, servletPath);
        // 若有权限则:响应
        if (authorities.contains(authority)) {
            chain.doFilter(request, response);
            return;
        }

        // 若没有权限: 重定向到403.jsp
        response.sendRedirect(request.getContextPath() + "/403.jsp");
        return;
    }

}

 

以上是关于应用4:利用Filter限制用户浏览权限的主要内容,如果未能解决你的问题,请参考以下文章

Django REST框架--认证和权限

为啥 Android 4.4 KitKat 限制第三方应用的 SD 卡读写权限

80%的手机用户面临浏览器安全风险

如何利用redis来进行分布式集群系统的限流设计

为啥 Android 4.4 KitKat 限制第三方应用的 SD 卡读写权限

Java项目怎么控制权限啊?