Spring Boot 3.3.2部分接口双认证配置后JWT访问异常求助
解决方案
问题出在你的b2bFilterChain配置及自定义过滤器逻辑中:
- 未集成OAuth2 JWT认证逻辑,导致带JWT的请求无法被解析认证;
- 使用
permitAll()跳过了认证校验,与"需认证通过才能访问"的需求冲突; - 自定义过滤器未判断已有认证信息,可能覆盖合法的JWT认证结果。
修改步骤:
1. 调整b2bFilterChain配置,同时支持JWT和自定义头认证
在b2b专属过滤器链中添加OAuth2资源服务器配置,并将权限校验改为authenticated():
@Bean @Order(1) public SecurityFilterChain b2bFilterChain(HttpSecurity http) throws Exception { http .securityMatcher("/api/b2b/**") .csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests(authz -> authz .anyRequest().authenticated() // 要求必须认证通过,支持两种方式 ) .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()) // 启用JWT认证逻辑 ) .addFilterBefore(new B2BAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); return http.build(); }
2. 修改自定义过滤器逻辑,仅在无认证时处理自定义头
确保只有当请求未通过JWT认证时,才尝试用自定义头校验,避免覆盖合法的JWT认证信息:
@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // 检查当前是否已有合法认证 Authentication existingAuth = SecurityContextHolder.getContext().getAuthentication(); if (existingAuth == null || !existingAuth.isAuthenticated()) { String customToken = request.getHeader("X-Custom-Token"); if (customToken != null) { // 替换为你的真实校验逻辑:验证customToken有效性,获取用户权限等 List<GrantedAuthority> authorities = Arrays.asList(new SimpleGrantedAuthority("ROLE_B2B_USER")); // 生成已认证的Authentication对象(AnonymousAuthenticationToken是未认证状态,会被authenticated()拒绝) Authentication auth = new UsernamePasswordAuthenticationToken( "b2b-authenticated-user", // 用户名/用户标识 null, // 凭证,自定义认证可设为null authorities // 用户权限 ); SecurityContextHolder.getContext().setAuthentication(auth); } } filterChain.doFilter(request, response); }
原理说明:
b2bFilterChain现在同时包含JWT认证过滤器和自定义认证过滤器,两种认证方式独立生效;- 当请求携带JWT时,OAuth2的
JwtAuthenticationFilter会优先解析并生成合法的Authentication,自定义过滤器会跳过处理; - 当请求携带
X-Custom-Token但无JWT时,自定义过滤器会校验并生成已认证的Authentication; authenticated()确保只有通过任意一种认证的请求才能访问/api/b2b/**接口,符合你的需求。
内容的提问来源于stack exchange,提问作者FeXseven
相关产品推荐
相关产品推荐

