SpringBoot实现登录拦截器

VSole2022-03-22 16:20:08

对于管理系统或其他需要用户登录的系统,登录验证都是必不可少的环节,在 SpringBoot 开发的项目中,通过实现拦截器来实现用户登录拦截并验证。

1、SpringBoot 实现登录拦截的原理

SpringBoot 通过实现HandlerInterceptor接口实现拦截器,通过实现WebMvcConfigurer接口实现一个配置类,在配置类中注入拦截器,最后再通过 @Configuration 注解注入配置.

1.1、实现HandlerInterceptor接口

实现HandlerInterceptor接口需要实现 3 个方法:preHandlepostHandleafterCompletion.

3 个方法各自的功能如下:

package blog.interceptor;

import blog.entity.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class UserLoginInterceptor implements HandlerInterceptor {

    /***
     * 在请求处理之前进行调用(Controller方法调用之前)
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("执行了拦截器的preHandle方法");
        try {
            HttpSession session = request.getSession();
            //统一拦截(查询当前session是否存在user)(这里user会在每次登录成功后,写入session)
            User user = (User) session.getAttribute("user");
            if (user != null) {
                return true;
            }
            response.sendRedirect(request.getContextPath() + "login");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
        //如果设置为false时,被请求时,拦截器执行到此处将不会继续操作
        //如果设置为true时,请求将会继续执行后面的操作
    }

    /***
     * 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("执行了拦截器的postHandle方法");
    }

    /***
     * 整个请求结束之后被调用,也就是在DispatchServlet渲染了对应的视图之后执行(主要用于进行资源清理工作)
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("执行了拦截器的afterCompletion方法");
    }
}

preHandle在 Controller 之前执行,因此拦截器的功能主要就是在这个部分实现:

  1. 检查 session 中是否有user对象存在;
  2. 如果存在,就返回true,那么 Controller 就会继续后面的操作;
  3. 如果不存在,就会重定向到登录界面
  4. 就是通过这个拦截器,使得 Controller 在执行之前,都执行一遍preHandle.

1.2、实现WebMvcConfigurer接口,注册拦截器

实现WebMvcConfigurer接口来实现一个配置类,将上面实现的拦截器的一个对象注册到这个配置类中.

package blog.config;

import blog.interceptor.UserLoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class LoginConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //注册TestInterceptor拦截器
        InterceptorRegistration registration = registry.addInterceptor(new UserLoginInterceptor());
        registration.addPathPatterns("/**"); //所有路径都被拦截
        registration.excludePathPatterns(    //添加不拦截路径
                "/login",                    //登录路径
                "/**/*.html",                //html静态资源
                "/**/*.js",                  //js静态资源
                "/**/*.css"                  //css静态资源
        );
    }
}

将拦截器注册到了拦截器列表中,并且指明了拦截哪些访问路径,不拦截哪些访问路径,不拦截哪些资源文件;最后再以 @Configuration 注解将配置注入。

1.3、保持登录状态

只需一次登录,如果登录过,下一次再访问的时候就无需再次进行登录拦截,可以直接访问网站里面的内容了。

在正确登录之后,就将user保存到session中,再次访问页面的时候,登录拦截器就可以找到这个user对象,就不需要再次拦截到登录界面了.

@RequestMapping(value = {"", "/", "/index"}, method = RequestMethod.GET)
public String index(Model model, HttpServletRequest request) {
    User user = (User) request.getSession().getAttribute("user");
    model.addAttribute("user", user);
    return "users/index";
}

@RequestMapping(value = {"/login"}, method = RequestMethod.GET)
public String loginIndex() {
    return "users/login";
}

@RequestMapping(value = {"/login"}, method = RequestMethod.POST)
public String login(@RequestParam(name = "username")String username, @RequestParam(name = "password")String password,
                    Model model, HttpServletRequest request) {
    User user = userService.getPwdByUsername(username);
    String pwd = user.getPassword();
    String password1 = MD5Utils.md5Code(password).toUpperCase();
    String password2 = MD5Utils.md5Code(password1).toUpperCase();
    if (pwd.equals(password2)) {
        model.addAttribute("user", user);
        request.getSession().setAttribute("user", user);
        return "redirect:/index";
    } else {
        return "users/failed";
    }
}

2、代码实现及示例

代码实现如上所示。

在登录成功之后,将user信息保存到session中,下一次登录时浏览器根据自己的SESSIONID就可以找到对应的session,就不要再次登录了,可以从 Chrome 浏览器中看到。

3、效果验证

3.1、访问 localhost:8081/index 页面:

被重定向到了 localhost:8081/login,实现了登录拦截。

3.2、正确输入用户名和密码登录

3.3、再次访问 localhost:8081/index

没有再次被登录拦截器拦截,证明可以保持登录.

作者:Kant101
https://blog.csdn.net/qq_27198345/article/details/111401610
session
本作品采用《CC 协议》,转载必须注明作者和本文链接
会话机制Cookie/Session:在web应用中,常用的会话追踪机制是Cookie和Session
跨语言移植一直是技术领域内难以解决的问题,需要解决语言之间的约束,好在先前我们成功使用 Go 实现了 IIOP 协议通信,有了前车之鉴,所以这次我们将继续使用跨语言方式实现 Flask Session 伪造。本文以 Apache Superset 权限绕过漏洞(CVE-2023-27524) 为例讲述我们是如何在 Go 中实现 Flask 框架的 Session 验证、生成功能的。
在一次浏览某推中发现了发现了了一个web challenge的赏金ctf,这里从来学习一下由于使session_start()报错引发的危害。page=showMeTheCode程序分析index.php define; class Session{ public static $id = null; protected static $isInit = false; protected static $started = false; public static function start(){ self::$isInit = true; if (!
域内定位个人PC的三种方式
[VNCTF2022]gocalc0复现
2022-05-07 16:02:38
看雪论坛作者ID:H3h3QAQ
跨站请求伪造,也被称为“OneClick Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。 一、CSRF介绍 CSRF(Cross-site request forgery) 跨站请求伪造,也被称为“OneClick Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。
空会话意味着对网络资源的访问是在没有身份验证的情况下授予的。也称为匿名或访客访问,最常见的是IPC$ "Windows Named Pipe"共享。人们倾向于认为用户名是唯一的身份验证机制,在工作组中,这基本上是正确的。
1.验证码复用 漏洞描述 当服务器端受理请求后,没有将上一次保存的session及时清空,将会导致验证码可重复使用 通常情况下在网站注册、登录、找回密码等页面都会设计验证码验证。如果设计不合理,将会刀子验证码在验证成功一次之后,下次使用的就不在验证也就说可以重复使用。 案例: 可以看到此处前端登录虽有验证码验证,但是只验证一次。后续可一直使用该验证码。 测试方法:发送到repeater
IPC$ (Internet Process Connection) 是共享“命名管道”的资源,它是为了让进程间通信而开放的命名管道,通过提供可信任的用户名和口令,连接双方可以建立安全的通道并以此通道进行加密数据的交换,从而实现对远程计算机的访问。IPC$是NT2000的一项新功能,它有一个特点,即在同一时间内,两个IP之间只允许建立一个连接。
AuthMatrix 是一个Burp Suite扩展,用于检测权限授权问题,设置好session就能进行自动化测试。相似功能的插件还有:BurpSuite Authz。Authz会先访问一遍接口抓包,然后“Send request(s) to Authz”,设置低权限的cookie,“Run”就会使用低权限的cookie去请求,结果会匹配给出相似度百分比,可以查看每个请求的详细,半自动测试。
VSole
网络安全专家