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

如何实现OAuth2+JWT无状态认证中的JWT提取与响应头设置

实现OAuth2授权后提取JWT并设置到响应头的方案

刚好我之前做过类似的无状态OAuth2+JWT认证方案,你要实现的这个高亮步骤,核心就是重写Spring Security的OAuth2登录成功处理器,在授权回调完成后提取JWT并塞进响应头,下面是具体的实现步骤,一步步来就行:

1. 自定义OAuth2登录成功处理器

Spring Security在OAuth2授权兑换token成功后,会触发登录成功的事件,默认处理器只会做重定向操作。我们需要自定义一个处理器,插入提取JWT并设置响应头的逻辑。

创建一个继承SavedRequestAwareAuthenticationSuccessHandler的自定义处理器:

import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class CustomOAuth2SuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException {
        // 从认证上下文里提取OAuth2相关的认证信息
        if (authentication instanceof OAuth2Authentication) {
            OAuth2Authentication oAuth2Auth = (OAuth2Authentication) authentication;
            OAuth2AuthenticationDetails authDetails = (OAuth2AuthenticationDetails) oAuth2Auth.getDetails();
            // 提取授权服务器返回的JWT Token
            String jwtToken = authDetails.getTokenValue();
            
            // 将JWT写入响应头,这里自定义头名称,比如X-JWT-Token,方便前端识别
            response.setHeader("X-JWT-Token", jwtToken);
        }
        
        // 继续执行默认的重定向逻辑,回到用户最初请求的受保护资源(比如/)
        super.onAuthenticationSuccess(request, response, authentication);
    }
}

2. 配置Spring Security,替换默认处理器

接下来要把自定义的处理器绑定到Spring Security的OAuth2登录流程中,根据你的Spring Boot版本,有两种配置方式:

方式一:Spring Boot < 2.7(基于WebSecurityConfigurerAdapter)

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.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public CustomOAuth2SuccessHandler customOAuth2SuccessHandler() {
        return new CustomOAuth2SuccessHandler();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .oauth2Login()
                .successHandler(customOAuth2SuccessHandler()) // 绑定自定义成功处理器
                .and()
            .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS); // 开启无状态模式,符合你的需求
    }
}

方式二:Spring Boot >= 2.7(基于SecurityFilterChain)

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.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {

    @Bean
    public CustomOAuth2SuccessHandler customOAuth2SuccessHandler() {
        return new CustomOAuth2SuccessHandler();
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .anyRequest().authenticated()
            )
            .oauth2Login(oauth2 -> oauth2
                .successHandler(customOAuth2SuccessHandler()) // 绑定自定义成功处理器
            )
            .sessionManagement(session -> session
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 开启无状态会话
            );
        return http.build();
    }
}

3. 逻辑验证说明

  • 当授权服务器回调到/login?code=xxx&state=yyy时,Spring Security会自动完成code兑换access_token的流程,把OAuth2Authentication对象存入安全上下文。
  • 自定义处理器会拦截登录成功事件,从OAuth2AuthenticationDetails中提取JWT(也就是授权服务器返回的access_token,要确保授权服务器返回的是JWT格式)。
  • 处理器把JWT写入响应头后,会继续执行默认的重定向逻辑,回到用户最初请求的/路径。
  • 前端AngularJS加载/时,通过响应拦截器读取这个自定义响应头,将JWT存入localStorage,后续请求就可以通过httpInterceptor注入Authorization: Bearer <token>头完成认证。

额外注意事项

  • 确认你的OAuth2授权服务器返回的access_token是JWT格式,否则getTokenValue()拿到的内容无法被前端解析使用。
  • 响应头名称可以根据业务需求自定义,只要前端和后端保持一致即可。
  • 一定要配置SessionCreationPolicy.STATELESS,确保服务器端不创建会话,符合无状态认证的要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:16:21