You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中如何实现会话超时并重新要求登录

问题描述

我正在使用Spring Boot构建一个简单的JSON REST API,应用运行正常,已通过Spring Security配置Basic认证。但运行应用时,首次登录后刷新URL不会再次要求输入用户名密码,请问如何实现会话超时后重新提示登录?注:无UI,仅为API。

安全配置类

package com.erplogic.erp.topcon.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.http.SessionCreationPolicy;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfiguration {
    @Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests((authz) -> authz.anyRequest().authenticated()

        ).sessionManagement(session -> session
                .sessionCreationPolicy(SessionCreationPolicy.NEVER)
                )
        
        .httpBasic();
        return http.build();
    }

    @Bean
    InMemoryUserDetailsManager userDetailsService() {
        UserDetails user = User.builder().username("user").password(encoder().encode("pass")).roles("USER").build();
        return new InMemoryUserDetailsManager(user);
    }

    @Bean
    PasswordEncoder encoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    SessionRegistry sessionRegistry() {
        return new SessionRegistryImpl();
    }
}

控制器类

package com.erplogic.erp.topcon.controller;

import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.erplogic.erp.topcon.service.SapApiService;
import com.erplogic.poc.objects.Root;
import com.fasterxml.jackson.core.JsonProcessingException;

import io.erplogic.maven.plclog.wsdl2java.StandardFaultMessage_Exception;

@RestController
public class OutboundController {
    @Autowired
    private SapApiService sapApiService;

    
    @RequestMapping(path ="/outbound",produces = MediaType.APPLICATION_JSON_VALUE,method = RequestMethod.GET)
    public Root getOutbound() throws KeyManagementException, NoSuchAlgorithmException, StandardFaultMessage_Exception, JsonProcessingException {
        
        return ((SapApiService) sapApiService).processOutboudService();
    }
    @RequestMapping(value = "/outbound/{outboundId}",produces = MediaType.APPLICATION_JSON_VALUE,method = RequestMethod.GET)
    public String getOutboundId(@PathVariable String outboundId) throws KeyManagementException, JsonProcessingException, NoSuchAlgorithmException, StandardFaultMessage_Exception {
        
        
        return ((SapApiService) sapApiService).processOutboudServiceByID(outboundId);
    }

}
解决方案

问题核心在于当前会话策略配置为SessionCreationPolicy.NEVER,Spring Security不会创建服务器端会话,浏览器/API工具会自动缓存Basic认证凭证,每次请求自动携带,因此不会触发重新登录。要实现会话超时后重新认证,需按以下步骤修改:

1. 调整会话创建策略并配置超时处理

修改SecurityConfiguration中的filterChain方法,将会话创建策略改为IF_REQUIRED,同时配置会话超时时间和失效后的响应逻辑:

import javax.servlet.http.HttpServletResponse;

@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http.authorizeHttpRequests((authz) -> authz.anyRequest().authenticated())
        .sessionManagement(session -> session
                .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                .sessionTimeout(timeout -> timeout.inSeconds(300)) // 设置会话超时时间为5分钟
                .invalidSessionStrategy((request, response) -> {
                    // 会话失效时返回401未授权状态码
                    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                })
                .maximumSessions(1) // 限制单个用户只能有一个会话(可选)
                .sessionRegistry(sessionRegistry())
        )
        .httpBasic();
    return http.build();
}

2. 配置全局会话超时时间(可选)

也可以在application.properties中添加全局会话超时配置,与代码中的配置二选一即可:

# application.properties
server.servlet.session.timeout=300s

3. 关键说明

  • SessionCreationPolicy.IF_REQUIRED:Spring Security会在需要时创建服务器端会话,用于跟踪认证状态。
  • 会话超时后,服务器端会话失效,后续请求会返回401未授权状态,客户端(浏览器/API工具)会重新提示输入用户名密码。
  • 若使用Postman等API调用工具,需确保工具未自动缓存Basic认证凭证,否则可能仍会自动携带旧凭证,需手动清除缓存或重新添加认证信息。

内容的提问来源于stack exchange,提问作者S Mugunthan kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 19:09:23