SpringSecurity如何整合JWT

整合JWT

我们前几个小节,实现的是非前后端分离情况下的认证与授权的处理,目前大部分项目,都是使用前后端分离的模式。那么前后端分离的情况下,我们如何使用SpringSecurity来解决权限问题呢?最常见的方案就是SpringSecurity+JWT

认证流程
  • 同步认证:登录之后会自动被框架的过滤器拦截,然后或许用户信息进行认证

  • 前后端分离认证:自定义登录接口,主动调用框架进行认证,使用的是框架提供的认证管理器

认证实现
环境准备
  • 为了快速搞定环境,我们新创建一个项目springsecurity-jwt,注意把上一个demo工程的代码和pom都拷贝过来

  • 从zzyl-common模块中工具类JwtUtil拷贝到当前项目中 ,用于生成和验证 JWT令牌

pom文件依赖
java 复制代码
<!--JWT-->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.8.1</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>
<!--工具包-->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.0.M3</version>
</dependency>
<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.75</version>
</dependency>
定义认证管理器

自定义授权管理属于全局,我们需要让它被spring容器进行管理,所以我们可以把它配置在SecurityConfig配置类中

在SecurityConfig添加创建认证管理器的代码,如下:

java 复制代码
package com.itheima.project.web;

import com.itheima.project.entity.LoginDto;
import com.itheima.project.entity.UserAuth;
import com.itheima.project.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * @author sjqn
 */
@RestController
@RequestMapping("/security")
public class LoginController {

    @Autowired
    private AuthenticationManager authenticationManager;

    @PostMapping("/login")
    public String login(@RequestBody LoginDto loginDto){

        //包装用户的密码
        UsernamePasswordAuthenticationToken upat = new UsernamePasswordAuthenticationToken(loginDto.getUsername(),loginDto.getPassword());

        //需要一个认证管理器,来进行调用
        Authentication authenticate = authenticationManager.authenticate(upat);
        //判断认证是否成功
        if(authenticate.isAuthenticated()){
            //获取用户
            UserAuth userAuth = (UserAuth) authenticate.getPrincipal();
            //认证成功
            //生成jwt,返回
            Map<String,Object> map = new HashMap<>();
            map.put("user",userAuth);

            String token = JwtUtil.createJWT("itcast", 360000, map);
            return token;
        }
        return "";

    }
}
登录功能实现

有了认证管理器之后,我们就可以在自己的登录接口中来使用认证管理器完成认证的操作

下面是自定义接口完成认证

java 复制代码
package com.itheima.project.web;

import com.itheima.project.entity.LoginDto;
import com.itheima.project.entity.UserAuth;
import com.itheima.project.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * @author sjqn
 */
@RestController
@RequestMapping("/security")
public class LoginController {

    @Autowired
    private AuthenticationManager authenticationManager;

    @PostMapping("/login")
    public String login(@RequestBody LoginDto loginDto){

        //包装用户的密码
        UsernamePasswordAuthenticationToken upat = new UsernamePasswordAuthenticationToken(loginDto.getUsername(),loginDto.getPassword());

        //需要一个认证管理器,来进行调用
        Authentication authenticate = authenticationManager.authenticate(upat);
        //判断认证是否成功
        if(authenticate.isAuthenticated()){
            //获取用户
            UserAuth userAuth = (UserAuth) authenticate.getPrincipal();
            //认证成功
            //生成jwt,返回
            Map<String,Object> map = new HashMap<>();
            map.put("user",userAuth);

            String token = JwtUtil.createJWT("itcast", 360000, map);
            return token;
        }
        return "";

    }
}

LoginDto

java 复制代码
package com.itheima.project.entity;

import lombok.Data;

@Data
public class LoginDto {

    private String username;
    private String password;
}

修改自定义配置,由于目前是接口开发,无需在使用自定义登录页面,只需要放行登录接口就行了

java 复制代码
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

    //构建自定义配置
    http.authorizeHttpRequests().antMatchers("/security/login").permitAll();
    http.csrf().disable();
    return http.build();
}

测试

使用ApiFox测试

  • 输入正确的用户名和密码,则会返回jwt生成的token,也就说明认证成功了
相关推荐
开开心心就好4 分钟前
免费PDF处理软件,支持多种操作
运维·服务器·前端·spring boot·智能手机·pdf·电脑
一只叫煤球的猫7 分钟前
真实事故复盘:Redis分布式锁居然失效了?公司十年老程序员踩的坑
java·redis·后端
猴哥源码10 分钟前
基于Java+SpringBoot的农事管理系统
java·spring boot
全宝22 分钟前
🎨前端实现文字渐变的三种方式
前端·javascript·css
面朝大海,春不暖,花不开25 分钟前
Java网络编程:TCP/UDP套接字通信详解
java·网络·tcp/ip
yanlele1 小时前
前端面试第 75 期 - 2025.07.06 更新前端面试问题总结(12道题)
前端·javascript·面试
妮妮喔妮1 小时前
【无标题】
开发语言·前端·javascript
慕y2741 小时前
Java学习第十五部分——MyBatis
java·学习·mybatis
fie88891 小时前
浅谈几种js设计模式
开发语言·javascript·设计模式
A__tao1 小时前
SQL 转 Java 实体类工具
java·数据库·sql