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,也就说明认证成功了
相关推荐
(⊙o⊙)~哦34 分钟前
JavaScript substring() 方法
前端
无心使然云中漫步1 小时前
GIS OGC之WMTS地图服务,通过Capabilities XML描述文档,获取matrixIds,origin,计算resolutions
前端·javascript
Bug缔造者1 小时前
Element-ui el-table 全局表格排序
前端·javascript·vue.js
C-SDN花园GGbond1 小时前
【探索数据结构与算法】插入排序:原理、实现与分析(图文详解)
c语言·开发语言·数据结构·排序算法
xnian_2 小时前
解决ruoyi-vue-pro-master框架引入报错,启动报错问题
前端·javascript·vue.js
迷迭所归处2 小时前
C++ —— 关于vector
开发语言·c++·算法
麒麟而非淇淋2 小时前
AJAX 入门 day1
前端·javascript·ajax
架构文摘JGWZ3 小时前
Java 23 的12 个新特性!!
java·开发语言·学习
2401_858120533 小时前
深入理解MATLAB中的事件处理机制
前端·javascript·matlab
leon6253 小时前
优化算法(一)—遗传算法(Genetic Algorithm)附MATLAB程序
开发语言·算法·matlab