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

Spring Security如何支持多授权方式 自定义授权成功后禁用JWT校验

解决方案

核心思路是调整授权过滤器的执行顺序,让自定义授权过滤器优先级高于JWT授权过滤器,自定义校验通过后直接标记请求已授权,阻止后续JWT校验执行。

通用实现逻辑

  • 调整过滤器/中间件的执行顺序,将自定义授权校验逻辑放在JWT校验逻辑之前
  • 自定义校验通过后,直接给当前请求绑定已认证的身份上下文,同时给请求打标记跳过后续所有授权校验,或者直接返回成功终止授权链执行
  • 自定义校验不通过时,才放行到下一个JWT校验逻辑继续执行

不同框架的具体实现示例

1. Spring Boot 生态

你可以直接自定义一个OncePerRequestFilter实现,设置比默认JWT过滤器更高的优先级:

// 首先设置自定义过滤器优先级高于默认的JWT过滤器
@Component
@Order(Ordered.HIGHEST_PRECEDENCE + 1)
public class CustomAuthFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String authHeader = request.getHeader("Authorization");
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            String token = authHeader.substring(7);
            // 执行你公司自定义的token校验逻辑
            if (customTokenValidate(token)) {
                // 校验通过,直接绑定认证信息到SecurityContext
                Authentication auth = new UsernamePasswordAuthenticationToken(getUserByToken(token), null, getUserAuthorities(token));
                SecurityContextHolder.getContext().setAuthentication(auth);
                // 直接放行到业务接口,不会再走后续的JWT过滤器
                filterChain.doFilter(request, response);
                return;
            }
        }
        // 自定义校验不通过,放行到下一个过滤器(即JWT过滤器)继续校验
        filterChain.doFilter(request, response);
    }
}

如果是用Spring Security的配置,也可以直接在HttpSecurity配置里显式指定过滤器顺序:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilterBefore(customAuthFilter, UsernamePasswordAuthenticationFilter.class)
            // 剩余的JWT、权限配置保持不变
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .oauth2ResourceServer().jwt();
    }
}

2. Express.js 生态

调整中间件注册顺序,先注册自定义授权中间件,再注册JWT中间件:

// 自定义授权中间件
const customAuthMiddleware = (req, res, next) => {
  const authHeader = req.headers.authorization
  if (authHeader && authHeader.startsWith('Bearer ')) {
    const token = authHeader.slice(7)
    if (customTokenValidate(token)) {
      // 校验通过,绑定用户信息到req对象
      req.user = getUserByToken(token)
      // 直接跳过后续所有授权中间件,进入业务路由
      return next('route')
    }
  }
  // 校验不通过,进入下一个中间件(JWT校验)
  next()
}

// 注册中间件时,自定义的要放在JWT之前
app.use(customAuthMiddleware)
app.use(expressJwt({ secret: jwtSecret, algorithms: ['HS256'] }))

3. Django 生态

修改settings.py里的认证后端顺序,把自定义认证后端放在JWT认证后端前面:

# settings.py
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'yourapp.authentication.CustomAuth', # 自定义认证类放第一
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ]
}

自定义认证类实现:

from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed

class CustomAuth(BaseAuthentication):
    def authenticate(self, request):
        auth_header = request.META.get('HTTP_AUTHORIZATION')
        if not auth_header or not auth_header.startswith('Bearer '):
            return None
        token = auth_header.split(' ')[1]
        if custom_token_validate(token):
            user = get_user_by_token(token)
            return (user, None)
        # 校验不通过返回None,DRF会自动调用下一个认证类(JWT)
        return None

兜底兼容方案

如果你的框架不支持调整过滤器顺序,可以在原有JWT校验逻辑里加分支判断:拿到Bearer token后先判断是否符合自定义token的格式特征(比如长度、前缀特征、签名规则特征等),符合的话先走自定义校验,自定义校验通过直接返回成功,不通过再走JWT校验逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 15:06:02