0

0

Spring Boot API认证:会话管理与JWT令牌策略

心靈之曲

心靈之曲

发布时间:2025-09-14 12:52:12

|

269人浏览过

|

来源于php中文网

原创

spring boot api认证:会话管理与jwt令牌策略

本文探讨了在Spring Boot应用中实现API认证的有效策略,避免手动会话验证的冗余。我们将重点介绍如何利用Spring Security的会话管理功能自动处理JSESSIONID,确保只有有效会话才能访问受保护资源。同时,文章也将推荐并简要介绍基于JWT(OAuth 2.0)的无状态认证方案,为构建现代、可扩展的API提供更优选择。

在构建RESTful API时,确保所有受保护的端点(endpoint)只能被已认证的用户访问是核心安全需求。然而,在每个API方法中手动检查会话状态不仅繁琐,而且容易出错,例如:

// 不推荐的会话验证方式
public ResponseEntity createMessage(@RequestBody MessageCreateRequest messageCreateRequest, HttpSession session) {
    if (session.getAttribute("valid") != null && (Boolean) session.getAttribute("valid")) {
        // 业务逻辑
        return new ResponseEntity<>("Message created!", HttpStatus.OK);
    }
    return new ResponseEntity<>("Invalid Session", HttpStatus.UNAUTHORIZED);
}

这种模式显然不是最佳实践。Spring生态系统提供了强大的安全框架——Spring Security,能够以声明式的方式处理认证和授权,极大地简化了这一过程。

一、利用Spring Security实现自动会话验证

Spring Security是Spring应用程序的实际安全标准。它提供了一套全面的安全服务,包括认证、授权、会话管理等。通过配置Spring Security,我们可以让框架自动处理会话Cookie的验证,而无需在每个业务方法中手动干预。

1. 配置Spring Security会话管理

要启用Spring Security的会话管理功能,你需要添加spring-boot-starter-security依赖,并创建一个配置类来定义安全过滤器链。以下是核心配置:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.config.http.SessionCreationPolicy;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            // 配置请求授权
            .authorizeHttpRequests(authorize -> authorize
                .requestMatchers("/online").permitAll() // 允许所有人访问登录接口
                .anyRequest().authenticated() // 其他所有请求都需要认证
            )
            // 配置会话管理
            .sessionManagement(session -> session
                .sessionCreationPolicy(SessionCreationPolicy.ALWAYS) // 总是创建会话
            )
            // 禁用CSRF保护,因为REST API通常不使用会话,或者通过其他方式处理
            // 如果你的API会话敏感,请考虑启用并妥善处理CSRF
            .csrf(csrf -> csrf.disable())
            // 启用HTTP Basic认证或表单登录,根据需要选择
            // .httpBasic(Customizer.withDefaults()); // 启用HTTP Basic认证
            // .formLogin(Customizer.withDefaults()); // 启用表单登录
            ;
        return http.build();
    }

    // 你可能还需要一个UserDetailsService和PasswordEncoder来处理用户认证
    // @Bean
    // public UserDetailsService userDetailsService() {
    //     UserDetails user = User.withDefaultPasswordEncoder()
    //         .username("user")
    //         .password("password")
    //         .roles("USER")
    //         .build();
    //     return new InMemoryUserDetailsManager(user);
    // }
}

配置详解:

  • @Configuration@EnableWebSecurity: 标记这是一个Spring Security配置类。
  • filterChain(HttpSecurity http): 这是Spring Security 6及以上版本推荐的配置方式,用于构建SecurityFilterChain。
  • authorizeHttpRequests(authorize -> ...): 定义请求的授权规则。
    • requestMatchers("/online").permitAll(): 允许未经认证的请求访问/online路径(通常是登录接口)。
    • anyRequest().authenticated(): 规定所有其他请求都必须经过认证。
  • sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.ALWAYS)): 这是实现自动会话验证的关键。
    • SessionCreationPolicy.ALWAYS: 意味着Spring Security将始终为每个用户创建一个HTTP会话。当用户成功认证后,会话将被标记为有效。后续请求中携带的JSESSIONID Cookie将被Spring Security自动验证。如果Cookie无效或会话过期,Spring Security将阻止请求访问受保护资源,并返回401 Unauthorized错误。
  • csrf(csrf -> csrf.disable()): 对于无状态的REST API,通常会禁用CSRF保护,因为它主要用于基于表单的Web应用。如果你的API确实依赖于会话,并且会话敏感,请考虑启用并妥善处理CSRF。
  • 认证方式: 你需要配置具体的认证方式,例如HTTP Basic认证、表单登录或自定义认证。上述代码注释部分提供了示例。

2. 登录流程示例

在上述Spring Security配置下,你的登录接口可以简化为:

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;
import jakarta.servlet.http.HttpSession; // 注意:此处的HttpSession在实际认证后会被Spring Security管理

@RestController
public class OnlineMapping {
    // @Autowired
    // private UserRepository userRepository; // 假设有一个用户仓库

    @PostMapping(path = "/online")
    public ResponseEntity onlineRequest(@RequestBody OnlineRequest onlineRequest, HttpSession session) {
        // 实际应用中,这里会通过Spring Security的认证管理器进行认证
        // 例如,通过AuthenticationManager.authenticate(new UsernamePasswordAuthenticationToken(...))
        // 如果认证成功,Spring Security会自动创建或更新会话,并设置JSESSIONID
        // 如果认证失败,则返回401

        // 简化示例:假设认证成功
        if ("user".equals(onlineRequest.username) && "password".equals(onlineRequest.password)) {
            // Spring Security会处理会话的创建和JSESSIONID的设置
            // 你无需手动设置session.setAttribute("valid", true);
            return new ResponseEntity<>("You are now online, Enjoy!", HttpStatus.OK);
        } else {
            // 认证失败,Spring Security会处理会话的无效化
            return new ResponseEntity<>("Invalid login", HttpStatus.valueOf(401));
        }
    }
}

当用户成功登录后,Spring Security会在响应中设置一个名为JSESSIONID的Cookie。客户端在后续请求中携带此Cookie,Spring Security会自动验证其有效性。对于受anyRequest().authenticated()保护的端点,如果JSESSIONID无效或缺失,请求将被拒绝。

二、推荐:使用JWT令牌(OAuth 2.0标准)

尽管Spring Security的会话管理功能强大且易于使用,但对于现代的、无状态的RESTful API,尤其是面向移动应用、微服务架构或跨域场景,基于JWT(JSON Web Token)的认证方式通常是更优的选择。

Action Figure AI
Action Figure AI

借助Action Figure AI的先进技术,瞬间将照片转化为定制动作人偶。

下载

1. JWT的优势

  • 无状态性 (Statelessness): 服务器不需要存储会话信息。每个请求都携带所有必要的认证信息,减轻了服务器负担,易于水平扩展。
  • 跨域友好: JWT通过HTTP头传递,不受Cookie的同源策略限制,非常适合CORS(跨域资源共享)场景。
  • 去中心化: 令牌可以在不同服务间传递和验证,无需共享会话存储。
  • 移动应用支持: 移动客户端通常更倾向于使用令牌而非Cookie进行认证。

2. 实现JWT认证

Spring Security通过spring-boot-starter-oauth2-resource-server依赖提供了对JWT(作为OAuth 2.0资源服务器)的良好支持。其基本流程如下:

  1. 登录认证: 用户提供凭据(用户名/密码)给认证服务。
  2. 生成JWT: 认证服务验证凭据后,生成一个包含用户身份信息和过期时间的JWT,并使用密钥签名。
  3. 返回JWT: JWT作为响应的一部分返回给客户端。
  4. 客户端存储: 客户端(如浏览器、移动应用)将JWT存储起来(例如,在LocalStorage或Secure Storage)。
  5. 后续请求: 客户端在每次请求受保护资源时,将JWT放置在HTTP请求头的Authorization字段中,通常以Bearer前缀形式发送(例如:Authorization: Bearer )。
  6. 资源服务器验证: 资源服务器(API服务)接收到请求后,使用预设的公钥或共享密钥验证JWT的签名和有效性(是否过期、是否被篡改)。如果验证通过,则允许访问;否则,拒绝请求。

核心依赖:


    org.springframework.boot
    spring-boot-starter-oauth2-resource-server

Spring Security配置示例(JWT):

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.config.http.SessionCreationPolicy;

@Configuration
@EnableWebSecurity
public class JwtSecurityConfig {

    // 假设你有一个JWK Set URI或者一个静态的公钥
    // private final String jwkSetUri = "http://localhost:8080/oauth2/jwks"; // 示例

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(authorize -> authorize
                .requestMatchers("/online").permitAll() // 登录接口可能不需要JWT
                .anyRequest().authenticated() // 其他所有请求都需要JWT认证
            )
            .oauth2ResourceServer(oauth2 -> oauth2
                .jwt(jwt -> jwt.decoder(jwtDecoder())) // 配置JWT解码器
            )
            .sessionManagement(session -> session
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS) // JWT通常是无状态的
            )
            .csrf(csrf -> csrf.disable()); // REST API通常禁用CSRF
        return http.build();
    }

    @Bean
    public JwtDecoder jwtDecoder() {
        // 这里需要配置你的JWT解码逻辑
        // 如果你使用授权服务器,通常会配置JWK Set URI
        // return NimbusJwtDecoder.withJwkSetUri(this.jwkSetUri).build();

        // 如果你使用对称密钥,可以这样配置
        // SecretKey secretKey = Keys.hmacShaKeyFor("your-secret-key-that-is-at-least-32-bytes-long".getBytes());
        // return NimbusJwtDecoder.withSecretKey(secretKey).build();

        // 这是一个占位符,实际应用中需要根据你的JWT提供方进行配置
        throw new UnsupportedOperationException("JWT Decoder must be configured with a valid JWK Set URI or Secret Key.");
    }
}

注意事项:

  • 使用JWT时,sessionCreationPolicy通常设置为STATELESS,因为JWT本身是无状态的,服务器无需维护会话。
  • 你需要正确配置JwtDecoder,使其能够验证你的JWT令牌。这通常涉及提供授权服务器的JWK Set URI或共享的对称密钥。
  • JWT令牌的生成和颁发通常由一个单独的认证服务(如OAuth 2.0授权服务器)负责。

总结

无论是采用传统的基于会话的认证还是现代的JWT认证,Spring Security都提供了强大且灵活的框架来简化API的安全性实现。

  • 对于传统的Web应用或对会话状态有强依赖的场景,Spring Security的会话管理提供了一种成熟且易于配置的方案,通过JSESSIONID自动处理会话验证。
  • 对于需要高扩展性、跨域支持、面向移动/微服务的API,JWT令牌是更推荐的选择,它实现了无状态认证,但需要客户端在每次请求中携带令牌,并在服务器端进行验证。

在任何认证方案中,都应避免在代码中直接存储明文密码,即使是用于测试目的。始终使用安全的哈希算法(如BCrypt)对密码进行加密存储和比较。选择哪种认证方式应根据项目的具体需求和架构进行权衡。

相关专题

更多
spring框架介绍
spring框架介绍

本专题整合了spring框架相关内容,想了解更多详细内容,请阅读专题下面的文章。

102

2025.08.06

spring boot框架优点
spring boot框架优点

spring boot框架的优点有简化配置、快速开发、内嵌服务器、微服务支持、自动化测试和生态系统支持。本专题为大家提供spring boot相关的文章、下载、课程内容,供大家免费下载体验。

135

2023.09.05

spring框架有哪些
spring框架有哪些

spring框架有Spring Core、Spring MVC、Spring Data、Spring Security、Spring AOP和Spring Boot。详细介绍:1、Spring Core,通过将对象的创建和依赖关系的管理交给容器来实现,从而降低了组件之间的耦合度;2、Spring MVC,提供基于模型-视图-控制器的架构,用于开发灵活和可扩展的Web应用程序等。

389

2023.10.12

Java Spring Boot开发
Java Spring Boot开发

本专题围绕 Java 主流开发框架 Spring Boot 展开,系统讲解依赖注入、配置管理、数据访问、RESTful API、微服务架构与安全认证等核心知识,并通过电商平台、博客系统与企业管理系统等项目实战,帮助学员掌握使用 Spring Boot 快速开发高效、稳定的企业级应用。

68

2025.08.19

Java Spring Boot 4更新教程_Java Spring Boot 4有哪些新特性
Java Spring Boot 4更新教程_Java Spring Boot 4有哪些新特性

Spring Boot 是一个基于 Spring 框架的 Java 开发框架,它通过 约定优于配置的原则,大幅简化了 Spring 应用的初始搭建、配置和开发过程,让开发者可以快速构建独立的、生产级别的 Spring 应用,无需繁琐的样板配置,通常集成嵌入式服务器(如 Tomcat),提供“开箱即用”的体验,是构建微服务和 Web 应用的流行工具。

31

2025.12.22

Java Spring Boot 微服务实战
Java Spring Boot 微服务实战

本专题深入讲解 Java Spring Boot 在微服务架构中的应用,内容涵盖服务注册与发现、REST API开发、配置中心、负载均衡、熔断与限流、日志与监控。通过实际项目案例(如电商订单系统),帮助开发者掌握 从单体应用迁移到高可用微服务系统的完整流程与实战能力。

114

2025.12.24

PHP API接口开发与RESTful实践
PHP API接口开发与RESTful实践

本专题聚焦 PHP在API接口开发中的应用,系统讲解 RESTful 架构设计原则、路由处理、请求参数解析、JSON数据返回、身份验证(Token/JWT)、跨域处理以及接口调试与异常处理。通过实战案例(如用户管理系统、商品信息接口服务),帮助开发者掌握 PHP构建高效、可维护的RESTful API服务能力。

146

2025.11.26

json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

411

2023.08.07

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

3

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 8.2万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 3.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号