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

如何配置Spring Authorization Server兼容旧版Spring Security OAuth2?

兼容旧JWT令牌的Spring Authorization Server配置方案

要同时实现旧令牌验证兼容和新令牌格式匹配旧系统,需要从资源服务器和授权服务器两部分配合配置:

一、资源服务器:兼容旧令牌验证

资源服务器需要沿用旧版OAuth2使用的签名密钥和JWT解析规则,确保旧令牌能正常通过验证。

1. 配置签名密钥

如果旧系统使用对称密钥(DefaultTokenServices常用HS256对称算法),直接指定该密钥:

@Bean
public JwtDecoder jwtDecoder() {
    // 替换为旧系统实际使用的签名密钥
    String oldSigningKey = "your-old-signing-key-string";
    SecretKey secretKey = Keys.hmacShaKeyFor(oldSigningKey.getBytes(StandardCharsets.UTF_8));
    return NimbusJwtDecoder.withSecretKey(secretKey).build();
}

如果旧系统用RSA非对称密钥,加载对应公钥即可:

@Bean
public JwtDecoder jwtDecoder() throws Exception {
    Resource publicKeyResource = new ClassPathResource("old-public-key.pem");
    RSAPublicKey publicKey = (RSAPublicKey) KeyFactory.getInstance("RSA")
            .generatePublic(new X509EncodedKeySpec(FileCopyUtils.copyToByteArray(publicKeyResource.getInputStream())));
    return NimbusJwtDecoder.withPublicKey(publicKey).build();
}

2. 适配旧JWT声明(按需配置)

如果旧令牌的声明字段和Spring Security默认规则不一致(比如旧版用user_name而非sub、authorities而非scope),自定义转换器映射:

@Bean
public JwtAuthenticationConverter jwtAuthenticationConverter() {
    JwtGrantedAuthoritiesConverter authoritiesConverter = new JwtGrantedAuthoritiesConverter();
    authoritiesConverter.setAuthoritiesClaimName("authorities");
    authoritiesConverter.setAuthorityPrefix("ROLE_");

    JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
    converter.setJwtGrantedAuthoritiesConverter(authoritiesConverter);
    converter.setPrincipalClaimName("user_name");
    return converter;
}

在资源服务器安全链中应用该转换器:

@Bean
public SecurityFilterChain resourceServerFilterChain(HttpSecurity http) throws Exception {
    http
        .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
        .oauth2ResourceServer(oauth2 -> oauth2
            .jwt(jwt -> jwt
                .decoder(jwtDecoder())
                .jwtAuthenticationConverter(jwtAuthenticationConverter())
            )
        );
    return http.build();
}

二、授权服务器:生成兼容旧格式的新令牌

授权服务器需要配置令牌生成逻辑,确保新JWT的签名算法、密钥、声明字段与旧令牌完全一致。

1. 配置签名密钥与算法

沿用旧系统的签名密钥和算法:

@Bean
public JWKSource<SecurityContext> jwkSource() {
    String oldSigningKey = "your-old-signing-key-string";
    SecretKey secretKey = Keys.hmacShaKeyFor(oldSigningKey.getBytes(StandardCharsets.UTF_8));
    JWKSet jwkSet = new JWKSet(new OctetSequenceKey.Builder(secretKey)
            .algorithm(JWSAlgorithm.HS256)
            .keyID("old-system-key-id")
            .build());
    return new ImmutableJWKSet<>(jwkSet);
}

2. 自定义JWT声明映射

确保新令牌包含旧系统依赖的所有声明字段:

@Bean
public OAuth2TokenCustomizer<JwtEncodingContext> jwtTokenCustomizer() {
    return context -> {
        Authentication principal = context.getPrincipal();
        if (principal instanceof UserDetails userDetails) {
            // 映射旧版用户名声明
            context.getClaims().claim("user_name", userDetails.getUsername());
            // 映射旧版权限声明
            List<String> authorities = userDetails.getAuthorities().stream()
                    .map(GrantedAuthority::getAuthority)
                    .collect(Collectors.toList());
            context.getClaims().claim("authorities", authorities);
        }
        // 保持issuer与旧系统一致
        context.getClaims().issuer("http://your-old-auth-server-issuer-url");
    };
}

3. 配置授权服务器令牌生成逻辑

在授权服务器安全链中指定令牌生成规则:

@Bean
public SecurityFilterChain authorizationServerFilterChain(HttpSecurity http) throws Exception {
    OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
    http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
        .tokenGenerator(tokenGenerator(jwkSource(), jwtTokenCustomizer()));
    return http.build();
}

@Bean
public OAuth2TokenGenerator<?> tokenGenerator(JWKSource<SecurityContext> jwkSource, OAuth2TokenCustomizer<JwtEncodingContext> customizer) {
    JwtGenerator jwtGenerator = new JwtGenerator(jwkSource);
    jwtGenerator.setJwtCustomizer(customizer);
    return new DelegatingOAuth2TokenGenerator(jwtGenerator);
}

关键注意事项

  • 签名密钥必须和旧系统完全一致,包括字符编码,否则旧令牌会验证失败。
  • 用jwt.io解析旧令牌,对比所有声明字段,确保新令牌的字段名称、格式完全匹配。
  • 先在测试环境验证:用旧令牌访问资源服务器确认授权正常;用新授权服务器生成令牌,确认资源服务器能验证通过且业务逻辑不受影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 08:27:41