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

Spring Authorization Server如何限制客户端仅访问指定资源服务器?

实现Spring Authorization Server客户端与资源服务器的访问限制

可以实现这个需求,核心是通过配置客户端关联的资源服务器ID,并让资源服务器验证Token的受众(aud)字段来实现访问控制,具体步骤如下:

1. 在Authorization Server配置客户端关联资源服务器ID

修改你的RegisteredClientRepository配置,为每个客户端指定对应的资源服务器ID:

@Bean
public RegisteredClientRepository registeredClientRepository() {
    RegisteredClient spa1 = RegisteredClient.withId(UUID.randomUUID().toString())
        .clientId("client1")
        // 保留原有配置(授权类型、范围等)
        .redirectUri("http://127.0.0.1:3000/authorized")
        // 关联resourceServer1
        .resourceId("resourceServer1")
        .build();
    
    RegisteredClient spa2 = RegisteredClient.withId(UUID.randomUUID().toString())
        .clientId("client2")
        // 保留原有配置
        .redirectUri("http://127.0.0.1:3001/authorized")
        // 关联resourceServer2
        .resourceId("resourceServer2")
        .build();

    return new InMemoryRegisteredClientRepository(spa1, spa2);
}

这里的.resourceId()方法对应你提到的旧版Spring Security中.resourceIds()的作用,配置后Authorization Server生成的Access Token会将该ID写入aud(受众)字段。

2. 配置资源服务器验证受众字段

每个资源服务器需要配置自身的资源ID,并验证Token的aud字段是否匹配,只有匹配的Token才能访问该资源服务器的端点。

方式一:基于@EnableResourceServer的传统配置

@Configuration
@EnableResourceServer
public class ResourceServer1Config extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        // 指定当前资源服务器的ID,与客户端配置的resourceId对应
        resources.resourceId("resourceServer1");
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .anyRequest().authenticated();
    }
}

同理,ResourceServer2Config只需将resourceId改为"resourceServer2"即可。

方式二:基于Spring Security 5+的OAuth2资源服务器新配置

如果使用较新版本的Spring Security,推荐使用这种方式:

@Configuration
public class ResourceServer1Config {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .oauth2ResourceServer(oauth2 -> oauth2
                .jwt(jwt -> jwt
                    .audienceValidator(audienceValidator())
                )
            )
            .authorizeRequests(auth -> auth
                .anyRequest().authenticated()
            );
        return http.build();
    }

    private OAuth2TokenValidator<Jwt> audienceValidator() {
        // 验证Token的aud字段是否包含当前资源服务器ID
        OAuth2TokenValidator<Jwt> audienceValidator = new AudienceValidator("resourceServer1");
        return new DelegatingOAuth2TokenValidator<>(JwtValidators.createDefault(), audienceValidator);
    }

    static class AudienceValidator implements OAuth2TokenValidator<Jwt> {
        private final String targetAudience;

        AudienceValidator(String targetAudience) {
            this.targetAudience = targetAudience;
        }

        @Override
        public OAuth2TokenValidatorResult validate(Jwt token) {
            if (token.getAudience().contains(targetAudience)) {
                return OAuth2TokenValidatorResult.success();
            }
            return OAuth2TokenValidatorResult.failure(
                new OAuth2Error(OAuth2ErrorCodes.INVALID_TOKEN, "Token受众不匹配当前资源服务器", null)
            );
        }
    }
}

原理说明

  • 客户端配置resourceId后,Authorization Server生成的Access Token会将该ID加入aud字段;
  • 资源服务器通过验证Token的aud字段是否包含自身的资源ID,实现对客户端访问权限的限制:只有关联了该资源ID的客户端生成的Token,才能通过验证并访问资源端点。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 06:10:35