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

Spring Security 6:OAuth2登录后用JWT替代JSESSIONID

需求:Spring Security OAuth2登录后返回自定义JWT替代Session

我曾见过一些类似的技术讨论,但均与我的需求不完全匹配。例如我找到一篇《Spring Boot实现无状态OAuth2社交登录》的复杂指南,但其方案仍依赖Cookie,存在CSRF攻击风险,这是我想避免的。

我附上了一张图示说明我的目标。当前我使用Spring Security 6.2.0,默认配置下(相关代码及配置见下文),OAuth2授权流程完成后,回调响应会携带含JSESSIONID的Set-Cookie,采用有状态会话管理,用户数据默认存储在内存中。

我不喜欢这种方式有两个原因:

  • 内存中的会话会随应用重启丢失,即便改用数据库或Redis存储,也会在每次授权请求时增加额外的数据库查询。
  • 基于Cookie的认证易受CSRF攻击,HTTPS仅加密Cookie但仍会自动发送;而基于Authorization头的方案需前端主动附加,安全性更高。

我希望通过Authorization头传递JWT来替代JSESSIONID,具体是在应用的回调响应中返回自定义生成的JWT(与从授权服务获取的access token不同,后者将存储备用),请提供实现方法、文章或文档参考,非常感谢。


当前配置

SecurityConfiguration.java

@Configuration
public class SecurityConfiguration {

    private static final String[] SWAGGER_URLS = {
            "/v3/api-docs/**",
            "/swagger-ui/**",
            "/v2/api-docs/**",
            "/swagger-resources/**"
    };

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity, ClientRegistrationRepository clientRegistrationRepository) throws Exception {

        String base_uri = OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI;
        DefaultOAuth2AuthorizationRequestResolver resolver = new DefaultOAuth2AuthorizationRequestResolver(clientRegistrationRepository, base_uri);
        resolver.setAuthorizationRequestCustomizer(OAuth2AuthorizationRequestCustomizers.withPkce());

        return httpSecurity
                .authorizeHttpRequests(c -> {
                    // permit anyone to get to error pages
                    c.dispatcherTypeMatchers(DispatcherType.ERROR).permitAll();

                    // permit all swagger urls
                    c.requestMatchers(SWAGGER_URLS).permitAll();

                    // require authentication for all other cases
                    c.anyRequest().authenticated();
                })
                .oauth2Login(c -> {
                    c.authorizationEndpoint(auth -> auth.authorizationRequestResolver(resolver)); // use PKCE
                })
                .build();
    }

    // default SpringHttpFirewall is a bit too strict
    @Bean
    public HttpFirewall getHttpFirewall() {
        StrictHttpFirewall strictHttpFirewall = new StrictHttpFirewall();
        strictHttpFirewall.setAllowUrlEncodedDoubleSlash(true);
        return strictHttpFirewall;
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

application.properties(相关配置)

# GitHub OAuth2
spring.security.oauth2.client.registration.github.client-id=${GITHUB_CLIENT_ID}
spring.security.oauth2.client.registration.github.client-secret=${GITHUB_CLIENT_SECRET}
spring.security.oauth2.client.registration.github.scope=user:read

内容的提问来源于stack exchange,提问作者mvv

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 19:43:23