使用Spring Security和JWT实现安全认证机制

 更新时间:2024年11月04日 11:23:42   作者:( •̀∀•́ )920  
在现代 Web 应用中,安全认证和授权是保障数据安全和用户隐私的核心机制,Spring Security 是 Spring 框架下专为安全设计的模块,具有高度的可配置性和扩展性,而 JWT则是当前流行的认证解决方案,所以本文介绍了如何使用Spring Security和JWT实现安全认证机制

引言

在现代 Web 应用中,安全认证和授权是保障数据安全和用户隐私的核心机制。Spring Security 是 Spring 框架下专为安全设计的模块,具有高度的可配置性和扩展性。而 JWT(JSON Web Token) 则是当前流行的认证解决方案,因其无状态、可扩展性强等特点被广泛应用于微服务和移动应用中。

本文将从以下几个部分详细介绍如何使用 Spring Security 和 JWT 实现一个完整的认证机制:

  1. JWT 认证流程概述
  2. Spring Security 的基本配置
  3. JWT 生成与解析
  4. 基于 Spring Security 的 JWT 安全配置
  5. 实现用户登录和认证

1. JWT 认证流程概述

JWT 的认证流程如下:

  • 用户登录:用户通过用户名和密码发送请求给服务器。
  • 服务器验证:服务器验证用户身份,验证通过后生成 JWT Token。
  • Token 下发:服务器将生成的 Token 返回给客户端。
  • 后续请求携带 Token:客户端在后续请求中将 JWT Token 添加到请求头中,服务器通过解析和验证 Token 确认请求的合法性。

这种方式的核心优势在于 Token 是无状态的,服务器无需维护用户的会话信息,且 JWT 可在分布式系统中实现共享认证。

2. Spring Security 的基本配置

创建一个简单的 Spring Boot 项目,并添加 Spring Security 和 JWT 的依赖:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>0.9.1</version>
    </dependency>
</dependencies>

配置 SecurityConfig 类

创建 SecurityConfig 类以配置 Spring Security 基本设置:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/login").permitAll()
            .anyRequest().authenticated();
    }
}

上面的配置指定 /login 接口公开访问,其余接口需要认证后才能访问。

3. JWT 生成与解析

使用 JWT 库生成和解析 Token。创建 JwtUtil 工具类,实现生成和验证 JWT 的方法:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;

public class JwtUtil {

    private static final String SECRET_KEY = "mySecretKey";

    // 生成 JWT
    public static String generateToken(String username) {
        return Jwts.builder()
                   .setSubject(username)
                   .setIssuedAt(new Date())
                   .setExpiration(new Date(System.currentTimeMillis() + 86400000)) // 24小时有效期
                   .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                   .compact();
    }

    // 解析 JWT
    public static Claims parseToken(String token) {
        return Jwts.parser()
                   .setSigningKey(SECRET_KEY)
                   .parseClaimsJws(token)
                   .getBody();
    }
}

4. 基于 Spring Security 的 JWT 安全配置

在 Spring Security 过滤链中添加 JWT 过滤器。实现一个 JwtAuthenticationFilter 类,在每次请求时拦截并验证 Token:

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

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import io.jsonwebtoken.Claims;

public class JwtAuthenticationFilter extends BasicAuthenticationFilter {

    public JwtAuthenticationFilter(AuthenticationManager authManager) {
        super(authManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        String token = request.getHeader("Authorization");
        if (token == null || !token.startsWith("Bearer ")) {
            chain.doFilter(request, response);
            return;
        }

        Claims claims = JwtUtil.parseToken(token.replace("Bearer ", ""));
        String username = claims.getSubject();

        if (username != null) {
            UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(username, null, new ArrayList<>());
            SecurityContextHolder.getContext().setAuthentication(auth);
        }
        chain.doFilter(request, response);
    }
}

将 JwtAuthenticationFilter 过滤器添加到 SecurityConfig 中:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable()
        .authorizeRequests()
        .antMatchers("/login").permitAll()
        .anyRequest().authenticated()
        .and()
        .addFilter(new JwtAuthenticationFilter(authenticationManager()));
}

5. 实现用户登录和认证

创建一个登录控制器 AuthController,验证用户后生成 JWT:

import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;

@RestController
public class AuthController {

    @PostMapping("/login")
    public void login(@RequestParam String username, @RequestParam String password, HttpServletResponse response) {
        // 这里简单校验用户名密码
        if ("user".equals(username) && "password".equals(password)) {
            String token = JwtUtil.generateToken(username);
            response.setHeader("Authorization", "Bearer " + token);
        } else {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        }
    }
}

以上代码实现了一个简单的登录接口,用户登录成功后将返回 JWT Token,并将该 Token 存储在响应头中。

6. 测试与验证

  1. 获取 Token:使用客户端(例如 Postman)请求 /login 接口,得到包含 JWT Token 的响应头。
  2. 访问受保护接口:将 Token 添加到请求头 Authorization 中,再次请求受保护接口,验证是否可以成功访问。

结论

通过以上步骤,我们实现了一个基于 Spring Security 和 JWT 的安全认证系统。在实际项目中,可以进一步扩展此功能,例如集成数据库实现用户管理、配置 JWT 自动续签等。这种基于 JWT 的无状态认证适用于分布式系统和微服务架构,有助于提高系统的安全性和可扩展性。

以上就是使用Spring Security和JWT实现安全认证机制的详细内容,更多关于Spring Security JWT安全认证的资料请关注脚本之家其它相关文章!

相关文章

  • Java源码解析之HashMap的put、resize方法详解

    Java源码解析之HashMap的put、resize方法详解

    这篇文章主要介绍了Java源码解析之HashMap的put、resize方法详解,文中有非常详细的代码示例,对正在学习java的小伙伴们有很大的帮助,需要的朋友可以参考下
    2021-04-04
  • SpringBoot中读取application.properties配置文件的方法

    SpringBoot中读取application.properties配置文件的方法

    这篇文章主要介绍了SpringBoot中读取application.properties配置文件的三种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2023-02-02
  • Mybatis-Plus通过SQL注入器实现批量插入的实践

    Mybatis-Plus通过SQL注入器实现批量插入的实践

    本文主要介绍了Mybatis-Plus通过SQL注入器实现批量插入的实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • RabbitMq的5种模式及实例解读

    RabbitMq的5种模式及实例解读

    这篇文章主要介绍了RabbitMq的5种模式及实例解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • Java并发编程之CountDownLatch原理详解

    Java并发编程之CountDownLatch原理详解

    这篇文章主要介绍了Java并发编程之CountDownLatch原理详解,CountDownLatch类中使用了一个继承自AQS的共享锁Sync对象,构造CountDownLatch对象时会将传入的线程数值设为AQS的state值,需要的朋友可以参考下
    2023-12-12
  • 如何用Springboot快速整合shiro安全框架

    如何用Springboot快速整合shiro安全框架

    这篇文章主要介绍了如何用SpringBoot快速整合shiro安全框架,shiro原名Apache Shiro 是一个Java 的安全(权限)框架。Shiro 可以非常容易的开发出足够好的应用,感兴趣的同学可以参考阅读
    2023-04-04
  • java中replaceAll替换圆括号实例代码

    java中replaceAll替换圆括号实例代码

    正则表达式的保留字符主要有:圆括号、方括号、花括号、竖线、横线、点号、加号、星号、反斜杆等等,下面这篇文章主要给大家介绍了关于java中replaceAll替换圆括号的相关资料,需要的朋友可以参考下
    2022-10-10
  • SpringBoot自动装配Import示例详解

    SpringBoot自动装配Import示例详解

    SpringBoot中@Import注解的使用可以帮助开发者将指定的Bean或配置类导入到IOC容器中,该注解支持四种用法:导入Bean、导入配置类、实现ImportSelector接口和实现,感兴趣的朋友一起看看吧
    2024-09-09
  • 详解java实现HTTP请求的三种方式

    详解java实现HTTP请求的三种方式

    这篇文章主要介绍了java实现HTTP请求的三种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • 自己动手在Spring-Boot上加强国际化功能的示例

    自己动手在Spring-Boot上加强国际化功能的示例

    这篇文章主要介绍了自己动手在Spring-Boot上加强国际化功能的示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04

最新评论