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

Spring Security:如何从SecurityContextHolder的JWT中提取Subject

解决方案

直接处理Jwt类型

你的代码未针对Jwt类型做分支判断,导致走到else分支返回整个令牌字符串。修改代码,增加对Jwt实例的判断,直接调用getSubject()方法获取主题:

import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.context.SecurityContextHolder;

// 获取Principal
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String subject;

// 判断是否为Jwt类型
if (principal instanceof Jwt) {
    subject = ((Jwt) principal).getSubject();
} else if (principal instanceof UserDetails) {
    subject = ((UserDetails) principal).getUsername();
} else {
    subject = principal.toString();
}

更简洁的方式:使用@AuthenticationPrincipal注解

在控制器方法参数中直接注入Jwt对象,无需手动从SecurityContextHolder获取:

import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;

@GetMapping("/your-endpoint")
public String getCurrentSubject(@AuthenticationPrincipal Jwt jwt) {
    return jwt.getSubject();
}

自定义Principal(可选)

如果希望将Principal转换为自定义对象(比如你的用户实体),可以配置JwtAuthenticationConverter:

  1. 定义转换器Bean:
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.context.annotation.Bean;

@Bean
public JwtAuthenticationConverter jwtAuthenticationConverter() {
    JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
    // 自定义Principal转换逻辑,这里直接返回subject,也可以返回自定义UserDetails实现
    converter.setPrincipalClaimConverter(jwt -> jwt.getSubject());
    return converter;
}
  1. 将转换器添加到Security配置中:
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    return http
            .httpBasic().disable()
            .csrf().disable()
            .formLogin().disable()
            .anonymous().disable()
            .logout().disable()
            .authorizeHttpRequests(authorize -> authorize
                    .antMatchers("/actuator/**").permitAll()
                    .antMatchers("/gicar/**").permitAll()
                    .anyRequest().authenticated()
            )
            .oauth2ResourceServer(config -> 
                    config.jwt(jwtConfig -> jwtConfig.jwtAuthenticationConverter(jwtAuthenticationConverter()))
            )
            .build();
}

配置完成后,Principal将直接是你定义的类型(比如subject字符串),原有代码的else分支也能正确获取到主题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 13:10:30