SpringBoot3 + SpringSecurity6 + JWT

相关链接

Spring Security mvnrepository

1. pom 引入

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.27</version>
</dependency>

2. 创建 UserBO 实现 UserDetails(spring security 中)

public class UserBO implements UserDetails {
    private String password;
    private String username;
    private List<GrantedAuthority> authorities;
    private boolean accountNonExpired;
    private boolean accountNonLocked;
    private boolean credentialsNonExpired;
    private boolean enabled;
}

3. 创建 service 实现 UserDetailsService

@Service
public class UserDetailsDetailsService implements IUserDetailsService {

    @Autowired
    IAccountInfoService accountInfoService;
    
    @Override
    public UserBO loadUserByUsername(String username) throws UsernameNotFoundException {
        AccountInfo ai = accountInfoService.findByUsername(username);
        if (null == ai) {
            throw new UsernameNotFoundException("用户名/密码错误");
        }
        return UserBO.trans(ai);
    }
}

4. 创建自定义密码校验

@Component
public class CustomPasswordEncoder implements PasswordEncoder {
    @Override
    public String encode(CharSequence rawPassword) {
        // 自定义加密方法
        return rawPassword.toString();
    }

    @Override
    public boolean matches(CharSequence rawPassword, String encodedPassword) {
        String[] pwd = encodedPassword.split("&");
        return new BCryptPasswordEncoder().matches(rawPassword.toString() + "&" + pwd[1], pwd[0]);
        // 自定义验证方法
    }
}

6. 创建 jwt 服务(可以按照自己的来)

public interface IJwtService {

    /**
     * 用户名
     *
     * @param token 令牌
     * @return 名称
     */
    String extractUsername(String token) throws AuthenticationException;

    /**
     * 验证
     *
     * @param token 令牌
     * @return 结果
     */
    Boolean validateToken(String token);

    /**
     * 获取token
     *
     * @param payload 信息
     * @return token
     */
    String generateToken(Object payload);
}

7. 创建 jwt 实例 (可以按照自己的来)

@Service
public class JwtService implements IJwtService {

    static final JWTSigner JWT_SIGNER = JWTSignerUtil.hs256("!34ADASfhsrujwstrfhwdg@#$$@#efh3".getBytes());


    @Override
    public String extractUsername(String token) throws AuthenticationException {
        JWTPayload payload = JWTUtil.parseToken(token).getPayload();
        if (null != payload) {
            return payload.getClaim("username").toString();
        }
        throw new AuthenticationException();
    }

    @Override
    public Boolean validateToken(String token) {
        return JWTUtil.verify(token, JWT_SIGNER);
    }

    @Override
    public String generateToken(Object payload) {
        return JWTUtil.createToken(BeanUtil.beanToMap(payload, "id", "username", "authorities"), JWT_SIGNER);
    }
}

8. 创建 jwt 过滤器 (可以自定义)

@Component
public class JwtAuthFilter extends OncePerRequestFilter {

    @Autowired
    private IJwtService jwtService;

    @Autowired
    IUserDetailsService userDetailsService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String authHeader = request.getHeader("Authorization");
        String token = null;
        String username = null;
        if(authHeader != null && authHeader.startsWith("Bearer ")){
            token = authHeader.substring(7);
            username = jwtService.extractUsername(token);
        }

        if(username != null && SecurityContextHolder.getContext().getAuthentication() == null){
            UserDetails details = userDetailsService.loadUserByUsername(username);
            if(jwtService.validateToken(token)){
                UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(details, null, details.getAuthorities());
                authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            }

        }

        filterChain.doFilter(request, response);
    }
}

9. 创建认证config

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Autowired
    JwtAuthFilter jwtAuthFilter;

    @Autowired
    IUserDetailsService userDetailsService;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http.csrf(AbstractHttpConfigurer::disable)
                .authorizeHttpRequests((ahrc) ->
                        ahrc.requestMatchers("/auth/login")
                                .permitAll()
                                .requestMatchers("/**")
                                .authenticated())
                .authenticationProvider(authenticationProvider())
                .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
                .sessionManagement((smc) -> smc.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .build();

    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new CustomPasswordEncoder();
    }

    @Bean
    public AuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(userDetailsService);
        authenticationProvider.setPasswordEncoder(passwordEncoder());
        return authenticationProvider;
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
        return config.getAuthenticationManager();
    }

}

10. 编写登陆API

@RestController
@RequestMapping("/auth")
public class AuthController {

    @Autowired
    IJwtService jwtService;

    @Autowired
    AuthenticationManager authenticationManager;

    @PostMapping("/login")
    public IResult<?> login(@RequestParam("username") String username, @RequestParam("password") String password) {
        Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
        if(authentication.isAuthenticated()){
            Map<String, String> params = new HashMap<>();
            params.put("username", username);
            params.put("token", jwtService.generateToken(authentication.getPrincipal()));
            return ResultVO.success(params);
        } else {
            throw new UsernameNotFoundException("错误的请求");
        }
    }
}

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

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

相关文章

政安晨:【Keras机器学习示例演绎】(三十三)—— 知识提炼

目录 设置 构建 Distiller() 类 创建学生和教师模型 准备数据集 培训教师 将教师模型蒸馏给学生模型 从头开始训练学生进行比较 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras机器学习实战 希望政安晨的博客能够…

基于Spring Boot的医疗服务系统设计与实现

基于Spring Boot的医疗服务系统设计与实现 开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/idea 系统部分展示 医疗服务系统首页界面图&#xff0c;公告信息、医疗地图…

快速幂笔记

快速幂即为快速求出一个数的幂&#xff0c;这样可以避免TLE&#xff08;超时&#xff09;的错误。 传送门&#xff1a;快速幂模板 前置知识&#xff1a; 1) 又 2) 代码&#xff1a; #include <bits/stdc.h> using namespace std; int quickPower(int a, int b) {int…

容斥原理以及Nim基础(异或,SG函数)

容斥原理&#xff1a; 容斥的复杂度为O&#xff08;2^m)&#xff0c;所以可以通过&#xff0c;对于实现&#xff0c;一共2^n-1种&#xff0c;我们可以用二进制来实现 下面是AC代码&#xff1a; #include<bits/stdc.h> using namespace std; typedef long long LL; cons…

uniapp 文字转语音(文字播报、语音合成)、震动提示插件 Ba-TTS

简介&#xff08;下载地址&#xff09; Ba-TTS 是一款uniapp语音合成&#xff08;tts&#xff09;插件&#xff0c;支持文本转语音&#xff08;无服务费&#xff09;&#xff0c;支持震动提示。 支持语音合成&#xff0c;文本转语音支持震动&#xff08;可自定义任意震动效果…

【云原生】Docker 实践(四):使用 Dockerfile 文件的综合案例

【Docker 实践】系列共包含以下几篇文章&#xff1a; Docker 实践&#xff08;一&#xff09;&#xff1a;在 Docker 中部署第一个应用Docker 实践&#xff08;二&#xff09;&#xff1a;什么是 Docker 的镜像Docker 实践&#xff08;三&#xff09;&#xff1a;使用 Dockerf…

【LinuxC语言】信号的基本概念与基本使用

文章目录 前言一、信号的概念二、信号的使用2.1 基本的信号类型2.2 signal函数 总结 前言 在Linux环境下&#xff0c;信号是一种用于通知进程发生了某种事件的机制。这些事件可能是由操作系统、其他进程或进程本身触发的。对于C语言编程者来说&#xff0c;理解信号的基本概念和…

36.Docker-Dockerfile自定义镜像

镜像结构 镜像是将应用程序及其需要的系统函数库、环境、配置、依赖打包而成。 镜像是分层机构&#xff0c;每一层都是一个layer BaseImage层&#xff1a;包含基本的系统函数库、环境变量、文件系统 EntryPoint:入口&#xff0c;是镜像中应用启动的命令 其他&#xff1a;在…

从0开始学习制作一个微信小程序 学习部分(6)组件与事件绑定

系列文章目录 学习篇第一篇我们讲了编译器下载&#xff0c;项目、环境建立、文件说明与简单操作&#xff1a;第一篇链接 第二、三篇分析了几个重要的配置json文件&#xff0c;是用于对小程序进行的切换页面、改变图标、控制是否能被搜索到等的操作第二篇链接、第三篇链接 第四…

QT的TcpServer

Server服务器端 QT版本5.6.1 界面设计 工程文件&#xff1a; 添加 network 模块 头文件引入TcpServer类和TcpSocket&#xff1a;QTcpServer和QTcpSocket #include <QTcpServer> #include <QTcpSocket>创建server对象并实例化&#xff1a; /*h文件中*/QTcpServer…

基于SSM SpringBoot vue宾馆网上预订综合业务服务系统

基于SSM SpringBoot vue宾馆网上预订综合业务服务系统 系统功能 首页 图片轮播 宾馆信息 饮食美食 休闲娱乐 新闻资讯 论坛 留言板 登录注册 个人中心 后台管理 登录注册 个人中心 用户管理 客房登记管理 客房调整管理 休闲娱乐管理 类型信息管理 论坛管理 系统管理 新闻资讯…

Docker-Compose编排LNMP并部署WordPress

前言 随着云计算和容器化技术的快速发展&#xff0c;使用 Docker Compose 编排 LNMP 环境已经成为快速部署 Web 应用程序的一种流行方式。LNMP 环境由 Linux、Nginx、MySQL 和 PHP 组成&#xff0c;为运行 Web 应用提供了稳定的基础。本文将介绍如何通过 Docker Compose 编排 …

BUUCTF---misc---被偷走的文件

1、题目描述 2、下载附件&#xff0c;是一个流量包&#xff0c;拿去wireshark分析&#xff0c;依次点开流量&#xff0c;发现有个流量的内容显示flag.rar 3、接着在kali中分离出压缩包&#xff0c;使用下面命令&#xff0c;将压缩包&#xff0c;分离出放在out3文件夹中 4、在文…

Java -- (part21)

一.File类 1.概述 表示文件或者文件夹的路径抽象表示形式 2.静态成员 static String pathSeparator:路径分隔符:; static String separator:名称分隔符:\ 3.构造方法 File(String parent,String child) File(File parent,String child) Flie(String path) 4.方法 获…

在M1芯片安装鸿蒙闪退解决方法

在M1芯片安装鸿蒙闪退解决方法 前言下载鸿蒙系统安装完成后&#xff0c;在M1 Macos14上打开闪退解决办法接下来就是按照提示一步一步安装。 前言 重新安装macos系统后&#xff0c;再次下载鸿蒙开发软件&#xff0c;竟然发现打不开。 下载鸿蒙系统 下载地址&#xff1a;http…

Android使用kts上传aar到JitPack仓库

Android使用kts上传aar到JitPack 之前做过sdk开发&#xff0c;需要将仓库上传到maven、JitPack或JCenter,但是JCenter已停止维护&#xff0c;本文是讲解上传到JitPack的方式,使用KTS语法&#xff0c;记录使用过程中遇到的一些坑. 1.创建项目(library方式) 由于之前用鸿神的w…

每日OJ题_贪心算法二⑥_力扣409. 最长回文串

目录 力扣409. 最长回文串 解析代码 力扣409. 最长回文串 409. 最长回文串 难度 简单 给定一个包含大写字母和小写字母的字符串 s &#xff0c;返回 通过这些字母构造成的 最长的回文串 。 在构造过程中&#xff0c;请注意 区分大小写 。比如 "Aa" 不能当做一个…

【Java从入门到精通】Java继承

继承的概念 继承是java面向对象编程技术的一块基石&#xff0c;因为它允许创建分等级层次的类。 继承就是子类继承父类的特征和行为&#xff0c;使得子类对象&#xff08;实例&#xff09;具有父类的实例域和方法&#xff0c;或子类从父类继承方法&#xff0c;使得子类具有父…

Linux 麒麟系统安装

国产麒麟系统官网地址&#xff1a; https://www.openkylin.top/downloads/ 下载该镜像后&#xff0c;使用VMware部署一个虚拟机&#xff1a; 完成虚拟机创建。点击&#xff1a;“开启此虚拟机” 选择“试用试用开放麒麟而不安装&#xff08;T&#xff09;”&#xff0c;进入op…

React Native支持Tailwind CSS 语法

React Native支持Tailwind CSS 语法 一、前沿背景 回想下我们平时按照官方的规范进行书写样式是什么样&#xff1f; 是像下面这样&#xff1a; const MyComponent () > {return (<View><Text style{{ fontSize: 20 }}>开发者演示专用</Text></View…
最新文章