如何配置单个授权服务器以支持多客户端的多种授权请求?
授权服务器多授权类型配置问题
我们有一个供多客户端使用的授权服务器,部分客户端希望通过client_credentials授权类型,在/token端点提交clientId和clientSecret生成访问令牌;另一部分客户端采用authorization_code授权类型,先在/authorize端点生成授权码,再在/token端点提交授权码生成访问令牌。请问如何完成如下配置?
authorizationServerConfigurer .oidc(oidc -> oidc .providerConfigurationEndpoint(providerConfigurationEndpoint -> providerConfigurationEndpoint.providerConfigurationCustomizer(builder -> builder .grantTypes(grantTypesList) .tokenEndpointAuthenticationMethod("client_secret_post") )) ) .authorizationEndpoint(authEndpoint -> authEndpoint .authorizationRequestConverter(new AuthorizationRequestConverter()) ) .tokenEndpoint(//support authorization_code) .tokenEndpoint(//support client_credentials) ;
我曾尝试查找相关文档以寻求解决方案,但未找到清晰的配置方法。
解决方案
1. 声明支持的授权类型列表
首先要确保grantTypesList包含两种需要的授权类型,让OIDC配置正确对外声明服务器支持的类型:
List<String> grantTypesList = Arrays.asList("authorization_code", "client_credentials");
2. 统一配置Token端点&区分客户端授权类型
不需要重复调用.tokenEndpoint(),Spring Authorization Server的/token端点默认支持多种授权类型,核心是通过客户端详情配置为不同客户端分配对应的授权类型。完整配置示例如下:
// 定义客户端详情存储,为不同客户端配置对应授权类型 InMemoryRegisteredClientRepository clientRepository = new InMemoryRegisteredClientRepository( // 适配authorization_code类型的客户端 RegisteredClient.withId("code-client-id") .clientId("code-client") .clientSecret("{noop}code-client-secret") // 生产环境请使用加密存储 .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) .redirectUri("http://your-client-domain/login/oauth2/code/code-client") .scope(OidcScopes.OPENID) .build(), // 适配client_credentials类型的客户端 RegisteredClient.withId("credentials-client-id") .clientId("credentials-client") .clientSecret("{noop}credentials-client-secret") // 生产环境请使用加密存储 .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS) .scope("api.read") .build() ); // 整合到授权服务器配置中 authorizationServerConfigurer .oidc(oidc -> oidc .providerConfigurationEndpoint(providerConfigurationEndpoint -> providerConfigurationEndpoint.providerConfigurationCustomizer(builder -> builder .grantTypes(grantTypesList) .tokenEndpointAuthenticationMethod("client_secret_post") )) ) .authorizationEndpoint(authEndpoint -> authEndpoint .authorizationRequestConverter(new AuthorizationRequestConverter()) ) .tokenEndpoint(tokenEndpoint -> tokenEndpoint // 可按需配置响应转换器等,无需额外指定授权类型 .accessTokenResponseConverter(new OAuth2AccessTokenResponseHttpMessageConverter()) ) .clientRepository(clientRepository); // 关联客户端详情服务
3. 关键注意点
- 客户端类型区分:必须为不同客户端单独配置
authorizationGrantType,授权服务器会根据客户端的配置判断是否允许其使用对应授权类型。 - Token端点自动适配:只要客户端配置了合法的授权类型,且请求参数符合规范(比如
authorization_code需要携带授权码、client_credentials需要携带客户端凭证),/token端点会自动处理令牌生成逻辑。 - 认证方式统一:
tokenEndpointAuthenticationMethod("client_secret_post")指定了客户端通过POST提交凭证,两种授权类型的客户端都可使用该方式完成身份认证。
内容的提问来源于stack exchange,提问作者Mangalam Palod
相关产品推荐
相关产品推荐

