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

Spring Boot中如何为HandlerMethodArgumentResolver从请求头获取JwtAuthenticationToken

解决方案

完全可以直接获取已经解析好的JwtAuthenticationToken,不需要自己手动解析Authorization头的Bearer字符串。Spring Security完成JWT认证后,已经将生成的JwtAuthenticationToken存入SecurityContextHolder,你直接从上下文取即可。

实现步骤

1. 自定义HandlerMethodArgumentResolver

你可以选择两种实现方向,按需选择:

方向1:直接注入JwtAuthenticationToken

实现解析器,直接将JwtAuthenticationToken注入到控制器参数:

import org.springframework.core.MethodParameter;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

public class JwtAuthenticationTokenArgumentResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().equals(JwtAuthenticationToken.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        var authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication instanceof JwtAuthenticationToken jwtToken) {
            return jwtToken;
        }
        // 可根据业务需求替换为自定义未认证异常
        throw new RuntimeException("用户未认证");
    }
}

方向2:直接注入解析好的用户UID(更推荐,减少重复代码)

先自定义一个标识注解:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface CurrentUid {
}

再实现对应的参数解析器,把你原有的getUidFromToken逻辑搬到这里:

import org.springframework.core.MethodParameter;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

public class CurrentUidArgumentResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(CurrentUid.class) 
                && parameter.getParameterType().equals(String.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        var authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication instanceof JwtAuthenticationToken jwtToken) {
            // 替换为你原有提取UID的逻辑,比如从指定claim取值
            return jwtToken.getToken().getClaim("uid");
        }
        throw new RuntimeException("用户未认证");
    }
}

2. 注册参数解析器

把自定义的解析器注册到Spring MVC配置中:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        // 按需添加你自己实现的解析器
        // resolvers.add(new JwtAuthenticationTokenArgumentResolver());
        resolvers.add(new CurrentUidArgumentResolver());
    }
}

3. 控制器使用示例

如果用方向2,控制器代码可以简化为:

public ResponseEntity<String> getUserProfile(@CurrentUid String uid) {
    // 直接拿到解析好的uid,不需要再重复处理token
    // rest of the code
}

注意事项

  • 上述代码适用于Servlet环境的Spring Boot项目,如果是WebFlux反应式项目,需要替换为ReactiveSecurityContextHolder异步获取认证信息
  • 确保对应接口已经配置Spring Security认证规则,未经过认证的接口无法拿到有效的JwtAuthenticationToken

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 10:57:05