小工具      在线工具  汉语词典  dos游戏  css  js  c++  java

Servlet与Filter两种方式实现身份验证和访问控制

# Java Web,servlet,java,tomcat 额外说明

收录于:112天前

Servlet的session授权方式

<html>
<body>
<h2>Hello Welcome!</h2>
</body>

<form action="/security/index" method="get">
    Username: <input type="text" name="user"><br>
    Password: <input type="password" name="password"><br>
    <button type="submit">submit</button>
    <%= request.getAttribute("message")%>
</form>
</html>
@WebServlet("/login")
public class RedirectController extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        //转发
        req.getRequestDispatcher("index.jsp").forward(req,resp);


        //重定向
        //resp.sendRedirect("/servlet2");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        super.doPost(req, resp);
    }
}
@WebServlet("/index")
public class IdefyController extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        String name = req.getParameter("user");
        String password = req.getParameter("password");
        if (name.equals("xiaoxu") && password.equals("xiaoxu")){
    
            resp.getWriter().write("login successful!");
        }else {
    
            req.setAttribute("message","user or pass incorrect");
            req.getRequestDispatcher("index.jsp").forward(req,resp);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        super.doPost(req, resp);
    }
}

在这里插入图片描述
在这里插入图片描述
表单模拟的验证登录面临的新问题是这个验证登录只对index资源有效,不走验证流程,查看其他资源也可以访问,这显然是不对的。那么如何实现权限的控制呢?

会议技术会议

  • 创建会话
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    String name = req.getParameter("user");
    String password = req.getParameter("password");
    if (name.equals("xiaoxu") && password.equals("xiaoxu")){
    
        //session会话
        HttpSession session = req.getSession();
        session.setAttribute("isLogin","true");

        PrintWriter writer = resp.getWriter();
        writer.write("login successful!");
        writer.write("<a href=\"/exit\"></a>");

    }else {
    
        req.setAttribute("message","user or pass incorrect");
        req.getRequestDispatcher("index.jsp").forward(req,resp);
    }
}
//session会话
HttpSession session = req.getSession();
session.setAttribute("isLogin","true");

通过请求参数在HtppSession对象的实例中添加参数。对象的实例是全局的。服务器状态的会话技术通过添加表示来记录登录的状态。

  • 使用会话
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    if(req.getSession().getAttribute("isLogin") == null){
    
        resp.getWriter().write("Not currently logged in!");
    }else {
    
        if (req.getSession().getAttribute("isLogin").equals("true")){
    
            req.setCharacterEncoding("utf-8");
            PrintWriter out=resp.getWriter();
            out.write("Test");
        }else {
    
            resp.getWriter().write("Not currently logged in!");
        }
    }

req.getSession().getAttribute("isLogin")方法获取创建会话是存入会话的表示,确认登录状态。

当前未登录

在这里插入图片描述

直接访问资源

在这里插入图片描述

登录成功后

在这里插入图片描述
直接在url上访问资源

在这里插入图片描述
如上所示可以实现权限的管理,但缺点是每个资源都需要对session的判断,比较繁琐:

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    if(req.getSession().getAttribute("isLogin") == null){
    
        resp.getWriter().write("Not currently logged in!");
    }else {
    
        if (req.getSession().getAttribute("isLogin").equals("true")){
    
            req.setCharacterEncoding("utf-8");
            PrintWriter out=resp.getWriter();
            out.write("Test");
        }else {
    
            resp.getWriter().write("Not currently logged in!");
        }
    }
}
  • 消除会话

消除用户认证的核心是销毁会话中存储的身份:

//消除session会话
HttpSession session = request.getSession();
session.removeAttribute("isLogin");

Filter的授权方式

更多内容请移步Java开发网站核心servlet

public class LoginFilter implements Filter {
    

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    
        //super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    
        //请求和响应参数强转
        HttpServletRequest res = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;

        if(res.getSession().getAttribute("isLogin") == null){
    
            resp.getWriter().write("Not currently logged in!");
        }else {
    
            if (res.getSession().getAttribute("isLogin").equals("true")){
    
                filterChain.doFilter(servletRequest,servletResponse);
            }else {
    
                resp.getWriter().write("Not currently logged in!");
            }
        }
    }

    @Override
    public void destroy() {
    
        //super.destroy();
    }
}

这里将ServletRequest强转为HttpServletRequest

//请求和响应参数强转
HttpServletRequest res = (HttpServletRequest) servletRequest;
HttpServletResponse resp = (HttpServletResponse) servletResponse;

在这里插入图片描述

ServletRequest只是一个接口,实现了HttpServletRequest大多数方法,可以直接强转。

在web.xml配置fileter,也可以通过@WebFilter注解:

  <filter>
    <filter-name>webFilter</filter-name>
    <filter-class>com.example.controller.LoginFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>webFilter</filter-name>
    <url-pattern>/*</url-pattern> </filter-mapping> 

web.xml的配置是由加载顺序的,因此注意配置的顺序,利用顺序配置过滤器链,过滤器配置在servlet之前。/*表示所有路径。Filter的执行顺序与在web.xml配置文件中的配置顺序一致,一般把Filter配置在所有的Servlet之前。

配置完成后,启动服务器,直接控制主页的权限:

在这里插入图片描述
这里的解决方案是放开登录的主页即利用filter排除过滤不需要的页面:

<!--web.xml中过滤全部-->
  <filter>
    <filter-name>webFilter</filter-name>
    <filter-class>com.example.controller.LoginFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>webFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

在过滤器中捕获对应需要发布的URL:

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    
    //请求和响应参数强转
    HttpServletRequest res = (HttpServletRequest) servletRequest;
    HttpServletResponse resp = (HttpServletResponse) servletResponse;

    if (res.getServletPath().equals("/login") || res.getServletPath().equals("/index")){
    
        filterChain.doFilter(servletRequest,servletResponse);
    }else {
    
        if (res.getSession().getAttribute("isLogin") == null){
    
            resp.getWriter().write("Not currently logged in!");
        }
        if (res.getSession().getAttribute("isLogin").equals("true")){
    
            filterChain.doFilter(servletRequest,servletResponse);
        }
    }

}

之所以分别释放/login和/index,是因为前者是返回的登录页面,后者是登录权限判断的逻辑处理。 (如果不释放逻辑处理,会导致无法登录系统)

通过HttpServletRequest对象的实例的getServletPath()方法获取请求的uri,对特定的url直接释放资源例如:/login。注意需要带/

释放特定URI的资源后,只会释放特定的URI,其余的都会被拦截:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

这里需要注意的是释放url的逻辑。看下图Filter的处理逻辑。每个过滤器都可以过滤servlet,也可以通过url的配置来控制整个servlet:

在这里插入图片描述

案例的的filter的uri配置的是/*对所有的url拦截,需要释放登录和逻辑判断。Filter在拦截时,会对请求时拦截和请求后处理,这涉及到Filter的生命周期,只要释放了相应的uri其后的逻辑既可以正常执行,无论是页面还是处理逻辑。

过滤登录权限控制总结:

  1. 实现Filter类并重写方法
public class LoginFilter implements Filter {
    
	//重写方法
}
  1. 用户身份登录逻辑
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    
    //请求和响应参数强转
    HttpServletRequest res = (HttpServletRequest) servletRequest;
    HttpServletResponse resp = (HttpServletResponse) servletResponse;

	//需要释放的资源
    if (res.getServletPath().equals("/login") || res.getServletPath().equals("/index")){
    
        filterChain.doFilter(servletRequest,servletResponse);
    }else {
    
    	//状态判断
        if (res.getSession().getAttribute("isLogin") == null){
    
            resp.getWriter().write("Not currently logged in!");
        }
        if (res.getSession().getAttribute("isLogin").equals("true")){
    
            filterChain.doFilter(servletRequest,servletResponse);
        }
    }
}

请求和响应参数必须强制,因为ServletRequest只是一个接口,没有实现具体方法;登录页面和逻辑的资源必须释放;非登录逻辑相关必须验证登录状态并使用会话技术。

  1. 登录逻辑和会话技术

继承HttpServlet并实现相关方法,并在方法体中编写验证和会话逻辑。

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    

    String name = req.getParameter("user");
    String password = req.getParameter("password");
    if (name.equals("xiaoxu") && password.equals("xiaoxu")){
    
        //session会话
        HttpSession session = req.getSession();
        session.setAttribute("isLogin","true");

        PrintWriter writer = resp.getWriter();
        writer.write("login successful!");
    }else {
    
        req.setAttribute("message","user or pass incorrect");
        req.getRequestDispatcher("/login").forward(req,resp);
    }
}

不管是通过ajxa还是form,这里都会检查数据库,验证角色是否存在。如果存在,则设置会话 ID。如果不存在,则返回登录页面并返回错误信息。

servlet实现身份登录.zip

. . .

相关推荐

额外说明

【华为电脑试题JAVA实现详解】——密码拦截

   目录 一、题目描述 二、解题代码 一、题目描述 Catcher是MCA国的情报员,他工作时发现敌国会用一些对称的密码进行通信,比如像这些ABBA,ABA,A,123321,但是他们有时会在开始或结束时加入一些无关的字符以防止别国破解。比如进行下列变

额外说明

转:使用Java生成缩略图

生成缩略图的代码主要来源于:http://www.cnblogs.com/digdeep/p/4829471.html 有根据自己的业务进行封装,基本业务如下:图片上传之后,根据图片的原始宽度和系统设定的缩略图最大宽度计算出一个缩放比例,再根据这个比例计

额外说明

leetcode51(N皇后:回溯法)

n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。 给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。 每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇

额外说明

leetcode每日一题:数组(1/2)

-一个不甘平凡的普通人,日更算法学习和打卡,期待您的关注和认可,陪您一起学习打卡!!!--- -专栏:每日算法学习 -个人主页:个人主页 算法分类:数组篇练习 语言:java 题目来源:力扣 预期学习时间:两天 文章目录 你真的弄懂二分法么? 帮你弄懂二

额外说明

掌握Java中常用的数组操作方法

掌握Java中常用的数组操作方法 - 简单操作 -1. 创建数组: - 2. 访问数组元素: -3. 修改数组元素: -4. 获取数组长度: -5. 遍历数组: -6. 数组排序: -7. 数组拷贝: - 进阶操作 ⛄️1. 数组查找元素: ⛄️2. 数

额外说明

static的详细使用方法及例题

前言: 作者简介:爱吃大白菜1132 人生格言:纸上得来终觉浅,绝知此事要躬行   如果文章知识点有错误的地方不吝赐教,和大家一起学习,一起进步!   如果觉得博主文章还不错的话,希望三连支持! 目录   1. static修饰变量    a. 函数中局

额外说明

PartIII : 3_策略模式

定义: 策略模式 内容: 定义一系列的 算法, 把他们一个个 封装 起来, 并且使他们可互相替换。 本模式使得算法可 独立于 使用它的 客户而变化。 角色: 抽象策略 具体策略 上下文; 优点: 1.定义了一系列 可重用的算法和 行为; 2. 消除了 一

额外说明

vim配置+ctag像source insight一样方便阅读代码

1,配置amix/vimrc 在 https://github.com/amix/vimrc 下载 amix/vimrc 并安装: $ git clone --depth=1 https://github.com/amix/vimrc.git ~/.vi

额外说明

家居设计范例

研究了一下如何进行3D的家居设计,发现了一个好用的软件酷家乐,不需要安装到本地,直接在网站上进行在线设计就可以。具体用法也比较简单,按照户型图的尺寸来画墙,门窗等等,之后可以用素材库里面的家具来进行摆放,里面有不同的风格可以选择。 这里展示一下我的设计,

额外说明

一文读懂如何让网页变灰白色(黑白色)

文章目录 1. 文章引言 2. 实现方法 2.1 修改CSS文件 2.2 修改html标签 2.3 修改body标签 2.4 使用grayscale.js插件 1. 文章引言 有段时间,我们打开知名的网页,发现全部变成黑白色了,如下图所示: 一般在清明节

ads via 小工具