基于Filter的安全认证方式

1. 基于Filter的安全认证方式

  • 问题:基于session的安全认证方式存在一定的问题,例如对角色权限的认证都编码在了页面,一旦页面有很多,那我们必须在每个页面都去重复写角色权限认证逻辑,这样不便于维护和开发。因此我们可以通过Filter技术来控制整个模块的权限认证业务逻辑。

  • 原理:在对网站资源进行请求时,请求会先经过过滤器的过滤,如果过滤器放行才允许访问资源。

  • 工具:IDEA2018 + Tomcat8.0.45

  • 技术:Servlet + Filter + Session

  • 项目:Security_Filter

在这里插入图片描述

1.1 login.jsp

<%--
    @Description 系统登录页面
    @Author 周威
    @Date 2020-07-04 - 16:40
--%>
<%@ page language="java" contentType="text/html;charset=utf-8" %>
<html>
    <head>
        <title>登录</title>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
        <meta name="author" content="周威"/>
    </head>
    <body>
        <div>
            <h2>------------Welcome To Login Page---------</h2>
            <form action="${ pageContext.request.contextPath }/User/UserServlet.do" method="post">
                <p>UserName:<input name="username" type="text"></p>
                <p>PassWord:<input name="password" type="password"></p>
                <p><input type="submit" value="登录"></p>
            </form>
        </div>
    </body>
</html>

1.2 user_index.jsp

<%--
    @Description 用户首页
    @Author 周威
    @Date 2020-07-04 - 16:36
--%>
<%@ page language="java" contentType="text/html;charset=utf-8" %>
    <html>
        <head>
            <title>用户首页</title>
            <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
            <meta name="author" content="周威"/>
        </head>
    <body>
        Welcome ${ sessionScope.userName }
    </body>
</html>

1.3 web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!-- 配置欢迎页面 -->
    <welcome-file-list>
        <welcome-file>login.jsp</welcome-file>
    </welcome-file-list>

    <!-- 配置User模块过滤器 -->
    <filter>
        <filter-name>UserFilter</filter-name>
        <filter-class>zw.security.filter.UserFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>UserFilter</filter-name>
        <url-pattern>/User/*</url-pattern>
    </filter-mapping>

    <!-- 配置User模块登录控制器 -->
    <servlet>
        <servlet-name>UserServlet</servlet-name>
        <servlet-class>zw.security.servlet.UserServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>UserServlet</servlet-name>
        <url-pattern>/User/UserServlet.do</url-pattern>
    </servlet-mapping>
    
</web-app>

1.4 UserFilter.java

package zw.security.filter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class UserFilter implements Filter
{
    public void init(FilterConfig config) throws ServletException
    {

    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException
    {
        //1.获取HttpServlet相关对象
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        HttpSession session = request.getSession();

        //2.获取请求地址
        StringBuffer requestURL = request.getRequestURL();

        //3.判断是否是请求的User模块下的资源
        if(requestURL.toString().indexOf("/User") != -1)
        {
            //4.判断是否是请求User模块下的登录验证资源(有时还要放行User模块下的静态资源,如js,css,images)
            if(requestURL.toString().indexOf("/UserServlet.do") != -1)
            {
                chain.doFilter(request, response);
            }
            else
            {
                //5.取出Session中的用户角色信息
                String role = (String) session.getAttribute("role");

                //6.判断用户角色是否可以访问User模块下的资源
                if(role != null && "admin".equals(role))
                    chain.doFilter(request, response);
                else
                    response.sendRedirect("../login.jsp");
            }
        }
        else
            chain.doFilter(request, response);

    }

    public void destroy()
    {

    }

}

1.5 UserServlet.java

package zw.security.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * @ClassName UserServlet
 * @Description 用户登录处理Servlet类
 * @Author 周威
 * @Date 2020-07-04 - 16:04
 */
public class UserServlet extends HttpServlet
{
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        doPost(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        //1.设置request和response缓冲区字符集
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");

        //2.获取用户表单提交的用户名和密码
        String userName = request.getParameter("username");
        String passWord = request.getParameter("password");

        //3.进行用户登录认证,理论上要查询数据库,这里模拟存在一个username=root,password=root,role=admin的用户
        if(userName != null && passWord != null && "root".equals(userName) && "root".equals(passWord))
        {
            HttpSession session = request.getSession();

            //4.认证成功,将用户信息存入session
            session.setAttribute("userName", userName);
            session.setAttribute("passWord", passWord);
            session.setAttribute("role", "admin");

            //5.重定向到index.jsp页面
            response.sendRedirect("/User/user_index.jsp");
        }
        else
        {
            //6.认证失败,去login.jsp页面登录
            response.sendRedirect("/login.jsp");
        }
    }
}

1.5 测试

  • 首先我们启动tomcat,直接在地址栏输入http://127.0.0.1:8080/Security_Filter/index.jsp发现自动跳转到登录页面

  • 我们使用username=root,password=root进行登录,发现可以访问到index.jsp

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值