spring security怎么生成JWT返回前端,以及怎么自定义JWT认证过滤器

news2024/11/15 10:08:27

怎么生成JWT返回前端

1.先写一个类,里面含有jwt的生成解析验证过期时间的方法

package com.lzy.util;

import io.jsonwebtoken.*;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
@Data
@ConfigurationProperties(prefix = "lzy.jwt")

public class JwtUtil {
    Date date = new Date();
    private Long expireDate;
    private String SECRET_KEY;

    //生成JWT
    public String generateToken(String userName) {
        return Jwts.builder()
                .setHeaderParam("typ", "JWT") // 设置头部参数
                .setSubject(userName) // 设置主题或用户 ID
                .setIssuedAt(date) // 设置发行时间
                .setExpiration(new Date(date.getTime() + expireDate * 1000)) // 设置过期时间
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY) // 使用 HMAC SHA-256 算法和秘钥签名
                .compact(); // 生成 JWT 字符串
    }


    //解析JWT
    public Claims parseJwt(String jwt) throws Exception {
        try {
            // 解析 JWT 并返回 Claims 对象
            return Jwts.parser()
                    .setSigningKey(SECRET_KEY) // 设置秘钥
                    .parseClaimsJws(jwt)       // 解析 JWT 字符串
                    .getBody();                // 获取 Claims 对象
        } catch (Exception e) {
            return null;
        }
    }
    //JWT是否过期
    /**
     * 检测 JWT 是否过期
     *
     * @param claims JWT 的 Claims 对象
     * @return 是否已过期
     */
    public boolean isJwtExpired(Claims claims) {
        return claims.getExpiration().before(date);
    }

}

变量写在配置类

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/vueadmin?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
    username: root
    password: Qq702196
    driver-class-name: com.mysql.cj.jdbc.Driver
  redis:
    host: localhost
    port: 6379
    password: 123456
  security:
    user:
      name: lzy
      password: 123456
mybatis-plus:
  mapper-locations: classpath:mapper/*.xml
server:
  port: 9270
lzy:
  jwt:
    expireDate: 604800
    SECRET_KEY: fadboabdabodibnkjfbyervrtwqeqdfs


2.在成功执行器中引入

package com.lzy.security;

import cn.hutool.json.JSONUtil;
import com.lzy.common.lang.Result;
import com.lzy.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component

public class LoginSuccessHandler implements AuthenticationSuccessHandler {
    @Autowired
    JwtUtil jwtUtil;
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        // 将响应的内容类型设置为JSON
        response.setContentType("application/json;charset=utf-8");
        // 获取响应的输出流
        ServletOutputStream out = response.getOutputStream();
        //生成JWT,并且放置到请求头
        String jwt = jwtUtil.generateToken(authentication.getName());
        response.setHeader("Authorization", jwt);
        // 创建一个包含异常消息的Result对象
        Result result = Result.success("成功");
        // 将Result对象转换为JSON字符串,并写入输出流
        out.write(JSONUtil.toJsonStr(result).getBytes("UTF-8"));
        // 刷新输出流
        out.flush();
        // 关闭输出流
        out.close();
    }

    }

因为我这里前端是放入的localstorage

成功

怎么自定义JWT认证过滤器

1.先写一个JWT认证过滤器

package com.lzy.security;

import cn.hutool.core.util.StrUtil;
import com.lzy.util.JwtUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class JwtAuthenticationFilter extends BasicAuthenticationFilter {
    @Autowired
    JwtUtil jwtUtil;
    public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }
    //重写父类方法
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        //调用父类方法
        String jwt = request.getHeader("Authorization");
        //判断jwt是否为空
        if(StrUtil.isBlankOrUndefined(jwt)){
            chain.doFilter(request,response);
            return;
        }
        //解析jwt
        Claims claims = null;
        try {
            claims = jwtUtil.parseJwt(jwt);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        if(claims == null){
            throw new JwtException("token无效");
        }
        if (jwtUtil.isJwtExpired(claims)) {
            throw new JwtException("token已过期");
        }
        //获取用户名
        String username = claims.getSubject();
        //获取权限信息
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, null, null);
        //将用户名和权限信息放入SecurityContextHolder
        SecurityContextHolder.getContext().setAuthentication(token);
        //继续执行过滤器链
        chain.doFilter(request,response);


    }
}

2.再进行引用

package com.lzy.config;
 
import com.lzy.security.CaptchaFilter;
import com.lzy.security.JwtAuthenticationFilter;
import com.lzy.security.LoginFailureHandler;
import com.lzy.security.LoginSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) // 开启方法级别的权限注解
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    LoginFailureHandler loginFailureHandler;
    @Autowired
    LoginSuccessHandler loginSuccessHandler;
    @Autowired
    CaptchaFilter captchaFilter;
    @Bean
    JwtAuthenticationFilter jwtAuthenticationFilter() throws Exception {
        return new JwtAuthenticationFilter(authenticationManager());
    }


    private static final String[] URL_WHITELIST = {
            "/login",
            "/logout",
            "/captcha",
            "/favicon.ico", // 防止 favicon 请求被拦截
    };

    protected void configure(HttpSecurity http) throws Exception {

        //跨域配置
        http.cors().and().csrf().disable()
                //登录配置
                .formLogin()
                .successHandler(loginSuccessHandler).failureHandler(loginFailureHandler)
                //禁用session
                .and().sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                //配置拦截规则
                .and().authorizeRequests()
                //白名单
                .antMatchers(URL_WHITELIST).permitAll()
                //其他请求都需要认证
                .anyRequest().authenticated()
                //异常处理器
                .and().addFilter(jwtAuthenticationFilter())
                //配置自定义的过滤器
                .addFilterBefore(captchaFilter, UsernamePasswordAuthenticationFilter.class);

    }
 
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

7-6 分段函数2

计算分段函数&#xff0c;测试数据分别是-1、5、12。 输入格式: 输入一个数。 输出格式: 直接输出保留6位小数的结果&#xff0c;没有其它任何附加字符&#xff0c;没有宽度控制。 输入样例: 11输出样例: 0.999912输入样例: 7输出样例: 8.000000 #include <stdio.h…

单片机裸机程序——程序架构

目 录 程序架构等同于思想体系一、前后台顺序法二、时间片轮询法 程序架构等同于思想体系 建一栋楼房&#xff0c;地基要先设计好&#xff0c;而不是马上砌砖&#xff0c;地基和布局都合理&#xff0c;房子就住得舒服&#xff0c;也不会闹心。 写一段程序也一样&#xff0c;程…

c++,python实现网络爬虫

前言&#xff1a; 社交网络中用户生成的海量数据&#xff0c;社交网络数据的多样性和复杂性 如何高效地从海量的数据中获取和处理我们需要的信息资源&#xff1f; 该微博爬虫能够从社交网络平台中地提取文本、图片和用户之间的转发关系&#xff0c;并将这些数据结构化存储到…

Python的Windows GUI自动化之Pywinauto(四)

引言&#xff1a; 我们上章节中打开了一个应用程序后&#xff0c;并打印了所有的控件信息&#xff0c;这些对于工具无法定位到的控件有很好的协助作用&#xff08;当然这个可以作为主要的查找控件的用法&#xff0c;也可以辅助使用&#xff0c;我一般是把这个作为辅助使用&…

【C++】初识C++模板与STL

C语法相关知识点可以通过点击以下链接进行学习一起加油&#xff01;命名空间缺省参数与函数重载C相关特性类和对象-上篇类和对象-中篇类和对象-下篇日期类C/C内存管理 本章将简单分享C模板与STL相关知识&#xff0c;与之相关更多知识将留到下次更详细地来分享给大家 &#x1f3…

MySQL与ES数据实时同步,双写一致

一、简介 在项目的开发与运维过程中&#xff0c;MySQL 是业务数据库的核心角色&#xff0c;以其强大的事务处理能力和数据完整性保障&#xff0c;支撑着系统的稳定运行。随着数据量的急剧增长和查询复杂度的不断提升&#xff0c;单一依赖 MySQL 进行高效的数据检索显得日益吃力…

centos安装软件

1.centos 安装 unrar 提示找不到 使用EPEL仓库&#xff1a; 首先&#xff0c;你需要安装EPEL仓库&#xff1a; yum install epel-release 然后&#xff0c;尝试再次安装unrar&#xff1a; yum install unrar 编译安装&#xff1a; 下载源代码&#xff1a;wget http://www.rarla…

对耳朵伤害最小的耳机类型是哪种?五款口碑绝佳机型安利!

​目前来说&#xff0c;开放式耳机应该算是对耳朵伤害最小的耳机了。当今耳机市场上&#xff0c;开放式耳机以其舒适的佩戴和创新的非入耳设计赢得了众多消费者的喜爱。这种耳机让你在聆听音乐的同时&#xff0c;还能清晰地感知周围环境的声音&#xff0c;便于与人交流&#xf…

clickhouse 原理详解

1、MPP数据库简介 1.1、什么是OLTP与OLAP&#xff1f; 1.1.1、OLTP(OnLine Transaction Processing ) 联机事务处理 系统&#xff0c;例如mysql。擅长事务处理&#xff0c;在数据操作中保持着很强的一致性和原子性 &#xff0c;能够很好的支持频繁的数据插入和修改 &#x…

Java使用Tesseract进行OCR图片文字识别

前言 在当前的文字识别技术应用中&#xff0c;除了采用现有的API服务之外&#xff0c;常见的解决方案包括利用Tessdata、Canvas或OCRAD等工具。以下是对几种技术的简要分析&#xff1a; 百度API的使用体验表明&#xff0c;虽然其识别率令人满意&#xff0c;但并非完美无误。此…

一个月狂撸5.8W,利用AI制作宝宝走秀视频,让宝宝“出海”捞美刀

今天给大家分享的项目是**AI宝宝走秀视频玩法&#xff0c;**在项目拆解之前&#xff0c;先看一下这个账号。这个账号是在Tiktok上的&#xff0c;也就是海外版的抖音。 基本上都是几千万的播放&#xff0c;按照海外版抖音的激励计划&#xff0c;每播放一万次&#xff0c;就能赚8…

紧跟大模型技术趋势,为更大更通用的大模型提供底层支撑!关于智能计算系统:从深度学习到大模型,全新版本,发布!

文章目录 &#x1f4cb;前言&#x1f3af; 关于智能计算系统&#x1f3af; 内容简介&#x1f3af; 作者简介&#x1f3af; 专家推荐&#x1f3af; 目录大纲&#x1f525; 参与方式 &#x1f4cb;前言 “只要你想把大模型做得更好、做得更大、做得更快、做得更省电&#xff0c;…

翻译软件 Fastrans 开发日志 #01

目录 预览前言功能技术待办 预览 Github 仓库链接&#xff1a;https://github.com/YaoqxCN/Fastrans Gitee 仓库链接&#xff1a;https://gitee.com/yaoqx/Fastrans 求求给我点个 star 叭 qaq 现在才是 v1.0.0&#xff0c;给我个 star 鼓励我继续开发下去&#xff01; 我相信…

AI如何帮助普通人实现自我成长和副业变现

前言 最近有没有发现身边的一切都变得越来越"智能"了&#xff1f;连家里的空调都学会了自己调整温度&#xff0c;害得我每天起床都觉得它比我聪明。这不禁让我想到&#xff0c;既然连空调都在进化&#xff0c;我们这些普通人是不是也该搭上AI的快车&#xff0c;来个华…

找出所有子集异或和的和 全排列2

1863.找出所有子集异或和的和 解释&#xff1a;做本题没思路的话&#xff0c;强烈建议看本专栏上一篇博文 class Solution { public:int sum 0;int path 0;int subsetXORSum(vector<int>& nums) {dfs(nums, 0);return sum;}void dfs(vector<int>& nums,…

大模型分布式训练技术(DP、DDP和FSDP)

目录 数据并行&#xff08;PyTorch DP&#xff09; 分布式数据并行&#xff08;PyTorch DDP&#xff09; DP 与 DDP 的区别 补充说明&#xff1a;DP与DDP数据传输过程 完全分片数据并行(PyTorch FSDP) 补充说明&#xff1a;ZeRO FSDP DDP 与 FSDP 的区别 DP、DDP和FSD…

ADW400环保监测模块,用于各省市环保平台对接

ADW400环保监测模块主要用于计量低压网络的三相有功电能&#xff0c;同时可选择四个回路的电流输入&#xff0c;具有RS485通讯和470MHz无线通讯功能&#xff0c;方便用户进行用电监测、集抄和管理。可灵活安装于配电箱内&#xff0c;实现对不同区域和不同负荷的分项电能计量&am…

构建智慧园区的全方位解决方案:技术、部署与挑战应对

在当今数字化转型的浪潮中,智慧园区作为城市智能化的重要组成部分,正在成为各地政府和企业关注的焦点。本文将围绕一套完整的智慧园区解决方案,详细阐述其技术架构、部署流程以及在实施过程中可能遇到的挑战及应对策略。 1. 智慧园区解决方案概述 智慧园区解决方案旨在通过先…

Qt 一个带数据压缩的加解密实现类,压缩率达到了1/3

一.加解密效果 1-1000字符串,所占大小2890(加密前) 1-1000字符串,所占大小1964(加密后) 二.加解密功能实现类 /* Copyright (c) 2011, Andre Somers All rights reserved.Redistribution and use in…

Windows上安装 nodejs,npm 和 yarn详细教程

1、下载Node.js 访问Node.js 官网下载&#xff0c;下载需要版本版本&#xff0c;具体操作如下 2、安装Node.js 具体安装可参考以下知乎教程 https://www.zhihu.com/question/591831850/answer/3423661990 3、配置淘宝镜像 npm config set registry https://registry.npmmirror…