一文秒懂 springsecurity6.2实现自定义登录页

前言

springsecurity原理和基础这里暂时不讲,网上资料太多了,这个大家可以自行查找学习,基本上没什么太大区别,看几篇文章就了解了,这篇文章主要是针对自定义登录页做一个demo,通过这个小 demo,大家可以直接理解springsecurity 处理登录的流程。

在springsecurity 6.x之前的版本里,实现springsecurity web configuration 需要继承 WebSecurityConfigurerAdaper,但是在 6.X的新版本里,这个类已经不复存在了,而是使用 SpringSecurityFilterChain 而且有很多方法也都 depricated了,估计不久的将来,这些方法也会被 remove 掉,所以下面是基于springsecurity 6.2 版本实现的自定义登录页的功能,没有任何多余的代码,甚至从数据库查询user信息都是mock的,就是为了方便大家学习,网上看了很多资料,要么太繁琐,不知道核心在哪里,要么没办法复现,废话少说,直接上代码:

Springsecurity Filter Chain 配置:

package com.boot.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;


@Configuration
@EnableWebSecurity
public class SecurityConfig {

    /**
     * PasswordEncoder:加密编码,这里使用 NoOpPasswordEncoder 明文密码,如果需要加密,用 BCryptPasswordEncoder
     */
    @Bean
    public PasswordEncoder passwordEncoder(){
        //明文加密
        return NoOpPasswordEncoder.getInstance();
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(authorizeHttpRequests->
                authorizeHttpRequests
                        .requestMatchers("/login").permitAll()
//                        .requestMatchers(HttpMethod.POST, "/login").permitAll()
                        .anyRequest().authenticated()
        );
        http.formLogin(formLogin->
                formLogin
                        .loginPage("/mylogin.html")
                        .loginProcessingUrl("/login")
                        .permitAll()
        );
        // 注意 6.2 版本里这里要使用 csrf.disable() 而不是 withDefault() 方法,网上很多使用 withDefault()方法的,个人实践不成功
        http.csrf(csrf->csrf.disable());
        return http.build();
    }

}

写一个普通的 controller,后面我们就用这个 /user/login 做测试

@RestController
public class LoginController {

    @GetMapping("/user/login")
    public String login(){
        return "login";
    }

}

实现 UserDetailsService

package com.boot.service.impl;

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import org.springframework.security.core.userdetails.User;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        return User.withUsername("user")
                .password("123456")
                .build();

    }
}

这里只是简单的创建了一个 user,实际情况下可以在这里查询 db 里的user,为了简单化流程,这里就略过查询 db 的逻辑了,大家可以自行根据 mybatis 处理这一块内容

自定义的登录页

<!DOCTYPE html>
<html lang="en" xmlns:th="https://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
</head>
<body>
<h1 style="background-color: chocolate">欢迎登录</h1>
<form action="/login" method="post">
  用户名:<input type="text" name="username"><br/>
  密码:<input type="text" name="password"><br/>
  <input type="submit" value="登录">
</form>
</body>
</html>

注意这里的 form action 一定要和 SecurityConfig 里的 loginProcessUrl一致,具体原因后面讲,注意这个页面要放在 resources 下的 static 目录下,其他目录可能会跳转不成功

项目目录

简单说一下自定义登录页的原理

/**
 * 配置问题的主要问题点:
 *      1. http.csrf(withDefaults()); 这个方式禁用csrf已经不起作用了,必须要 http.csrf(csrf->csrf.disable());
 *      2. 表单里的 action 一定要是 /login
 *      3. loginProcessingUrl("/login") 这个 /login 接口只是一个虚拟的接口,springsecurity 一旦看到 endpoint/login 就会触发
 *          UsernamePasswordAuthenticationFilter 的校验逻辑,这个类会获取表单里的用户名和密码
 *
 *          在 Spring Security 中,所有的 HTTP 请求都会通过一系列的过滤器,这些过滤器组成了一个过滤器链。UsernamePasswordAuthenticationFilter
 *          就是其中的一个过滤器。每一个过滤器都对所有请求进行检查,看是否应该处理该请求。如果应该处理,该过滤器就会处理该请求;如果不应该处理,
 *          该过滤器就会将请求传递给过滤器链中的下一个过滤器。
 *
 *          UsernamePasswordAuthenticationFilter 的工作方式就是检查每个传入的 HTTP 请求,看是否是一个 POST 请求,且请求的路径是否匹配登录路径
 *          (默认是 /login,可以通过 .loginProcessingUrl("/yourLoginPath") 来修改)。如果满足这些条件,这个过滤器就会处理该请求,
 *          从请求参数中提取出用户名和密码,然后创建一个 UsernamePasswordAuthenticationToken,并将其传递给 AuthenticationManager。
 *
 *          这个过程是在 UsernamePasswordAuthenticationFilter 的 attemptAuthentication 方法中完成的。这个方法会检查请求的 HTTP 方法和路径,
 *          如果匹配,就处理该请求;如果不匹配,就返回 null,将处理权交给过滤器链中的下一个过滤器。
 *
 */

测试

访问 http://localhost:8886/user/login 会跳转到 mylogin.html 上:

输入用户名和密码,可以发现请求又被重定向回 /user/login 接口,而且访问成功:

Tips:

建议大家在测试的时候用 chrom 浏览器的隐身模式,快捷键: ctrl+shift+n

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/223021.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

无线4G电表有哪些优势?

无线4G电表是一种电力管理技术&#xff0c;它具有许多优势&#xff0c;使其成为现代社会中的重要应用。无线4G电表的主要特点是利用4G网络进行数据传输和通信&#xff0c;以取代传统的有线连接方式。那么&#xff0c;无线4G电表有哪些优势呢&#xff1f; 首先&#xff0c;无线4…

提高企业邮箱安全性的策略与技巧

提高企业邮箱的安全性的方法大体相同&#xff0c;每家邮箱供应商也可能会有自己独有防护措施。 为了增强Zoho Mail企业邮箱的安全性&#xff0c;您可参考以下建议&#xff1a; 采用强密码&#xff1a;创建包含大写字母、小写字母、数字和特殊字符的复杂密码&#xff0c;并定期…

vue中实现数字+英文字母组合键盘

完整代码 <template><div class"login"><div click"setFileClick">欢迎使用员工自助终端</div><el-dialog title"初始化设置文件打印消耗品配置密码" :visible.sync"dialogSetFile" width"600px&quo…

Powerbuilder9.0 安装是一直卡在setup is running无法继续

这种情况是安装时&#xff0c;他后面弹出来一个提示框&#xff0c;但是因为其他进程的干扰&#xff0c;我们无法看到也就无法继续了。 我看到这个文章&#xff1a;https://blog.csdn.net/FLORY_/article/details/105244102 使用他说的方法的确有效。过程 1. 打开任务管理器 …

【AI数字人-论文】DINet论文解读

DINet 方法形变修补损失函数perception lossGAN lossLip-sync loss 实现细节参考 如下图所示&#xff0c;人脸视觉配音&#xff08;Face visually dubbing&#xff09;旨在根据输入的驱动音频同步源视频中的嘴型&#xff0c;同时保持身份和头部姿势与源视频帧一致。然而在少样本…

子查询在SQL中的应用和实践

作者&#xff1a;CSDN-川川菜鸟 在SQL中&#xff0c;子查询是一种强大的工具&#xff0c;用于解决复杂的数据查询问题。本文将深入探讨子查询的概念、类型、规则&#xff0c;并通过具体案例展示其在实际应用中的用途。 文章目录 子查询概念子查询的类型子查询的规则实际案例分析…

leetcode 1658. 将 x 减到 0 的最小操作数(优质解法)

代码&#xff1a; class Solution {public int minOperations(int[] nums, int x) {int sum0; // nums 数组中的数据总和int lengthnums.length;for(int i0;i<length;i){sumnums[i];}int targetsum-x; //待查找的子数组的和if(target<0){return -1;}//采用滑动窗口的…

团建策划信息展示服务预约小程序效果如何

团建是中大型企业商家每年举办的员工活动&#xff0c;其形式多样化、具备全部参与的娱乐性。但在实际策划流程及内容时&#xff0c;部分公司便会难以入手&#xff0c;术业有专攻&#xff0c;这个时候团建策划公司便会发挥效果。 如拓展训练、露营、运动会、体育竞技等往往更具…

美格智能亮相中国企业家博鳌论坛:勇立创新潮头,5G+AIoT开启智能新时代

12月2日-5日&#xff0c;由新华社和海南省人民政府、中国品牌建设促进会等联合主办的2023中国企业家博鳌论坛在海南博鳌召开&#xff0c;包括众多世界500强、中国500强和行业领军企业家在内的3500多名社会各界嘉宾汇聚一堂&#xff0c;共谋中国经济高质量发展之道。 会议现场 …

知虾网:帮助卖家优化Shopee店铺运营的数据分析工具

在如今的电商时代&#xff0c;越来越多的卖家选择在Shopee平台上开设店铺。然而&#xff0c;随着竞争的加剧&#xff0c;如何提高店铺的曝光率和销售效果成为了卖家们面临的重要问题。为了帮助Shopee卖家更好地了解市场动态、优化商品策略、提高运营效果&#xff0c;知虾网应运…

LeetCode 每日一题 Day 4

2477. 到达首都的最少油耗 给你一棵 n 个节点的树&#xff08;一个无向、连通、无环图&#xff09;&#xff0c;每个节点表示一个城市&#xff0c;编号从 0 到 n - 1 &#xff0c;且恰好有 n - 1 条路。0 是首都。给你一个二维整数数组 roads &#xff0c;其中 roads[i] [ai,…

二叉树OJ题之三

哈喽伙伴们&#xff0c;有一段时间没更新博客了&#xff0c;主要是这段时间要准备学校的期末考试&#xff0c;所以没有把部分时间分给博客&#xff0c;今天我们一起去接着看二叉树递归有关的OJ题&#xff0c;今天我们要学习的是 判断相同的树&#xff0c;力扣题目--100 &…

2023年度亚太客户中心产业发展论坛——鸿联九五荣获亚太区卓越客服大赛客户运营管理类铂金大奖

11月27-28日&#xff0c; 2023年度亚太客户中心产业发展论坛暨亚太区卓越客服大赛在马来西亚吉隆坡举行。来自中国、澳大利亚、马来西亚、新加坡、中国香港、印度尼西亚和泰国等多个国家及地区的优秀企业代表齐聚吉隆坡。 论坛首日活动以“Experience Excellence, Meet the Cha…

Redis应用-缓存

目录 什么是缓存 使用redis作为缓存 缓存的更新策略 通用的淘汰策略 redis内置的淘汰策略 缓存预热 缓存穿透 缓存雪崩 缓存击穿 什么是缓存 缓存(cache)是计算机中一个经典的概念,在很多的场景中都会涉及到. 核心思路就是把一些常用的数据放到触手可及(访问速度更快…

javascript实现List列表数据结构

书籍推荐 有幸拜读《数据结构与算法Javascript描述》这本书&#xff0c;先强烈安利一波&#xff01;非常感谢作者大大给我们前端领域带来这本书。 全书从javascript的角度出发&#xff0c;简单明了的分析了数据结构在javascript领域的实现过程与实际的应用案例&#xff0c;且…

VA03 凭证流 查看备忘

今天被问到了&#xff0c;为什么这个销售订单 只显示了3 EA 仔细看了一下&#xff0c;前面10 是行项目 看销售订单 最后发现&#xff0c;凭证流跟选择查看的行项目有关系 以前一直没有关注这个细节

QT-在ui界面中给QWidget增加Layout布局的两种方法

QT-在ui界面中给QWidget增加Layout布局的两种方法 方式一 在UI界面&#xff0c;用拖拽的方式加入Layout方式二 用notepad软件打开.ui文件&#xff0c;手动加入Layout代码 目标&#xff1a;去除右下角红标&#xff0c;给tab标签增加Layout属性。 方式一 在UI界面&#xff0c;用…

nodejs+vue+ElementUi小区社区公寓宿舍智能访客预约系统

该系统将采用B/S结构模式&#xff0c;前端部分主要使用html、css、JavaScript等技术&#xff0c;使用Vue和ElementUI框架搭建前端页面&#xff0c;后端部分将使用Nodejs来搭建服务器&#xff0c;并使用MySQL建立后台数据系统&#xff0c;通过axios完成前后端的交互&#xff0c;…

生殖感染对生育的影响有哪些?劲松中西医结合医院专家详细解读

生殖感染是指由细菌、病毒、支原体、衣原体等病原微生物引起的生殖道感染&#xff0c;包括前列腺炎、尿道炎、宫颈炎、盆腔炎等。生殖感染对生育的影响是多方面的&#xff0c;今天劲松中西医结合医院谭巍主任将详细介绍这些影响及相应的预防办法。 一、影响生育能力的因素 1.…

❀My学习Linux命令小记录(14)❀

目录 ❀My学习Linux命令小记录&#xff08;14&#xff09;❀ 56.man指令 57.whatis指令 58.info指令 59.--help指令 60.uname指令 ❀My学习Linux命令小记录&#xff08;14&#xff09;❀ 56.man指令 功能说明&#xff1a;查看Linux中的指令帮助。 &#xff08;ps.man命…