我正在开发一个使用Spring Security 5.x的OAuth2支持登录的应用程序。我的一个用例需要为同一个OAuth2身份提供程序进行多个客户端注册,然后在给定与范围内OAuth2客户端对应的ClientRegistration
对象的情况下在运行时查找提供者ID。是否有提供此信息的公共API?
ClientRegistration
API:https://docs.spring.io/spring-security/site/docs/5.1.5.RELEASE/api/org/springframework/security/oauth2/client/registration/ClientRegistration.html不会公开此信息。
我曾希望ProviderDetails
:https://docs.spring.io/spring-security/site/docs/5.1.5.RELEASE/api/org/springframework/security/oauth2/client/registration/ClientRegistration.ProviderDetails.html会包括它,但那里没有运气。
我正在使用带有YAML配置的Spring Boot 2.x.客户端注册数据中provider
键的值正是我在运行时需要访问的值:
spring:
security:
oauth2:
provider:
myprovider:
authorization-uri: "https://oauth2.example.com/authorize"
jwk-set-uri: "https://oauth2.example.com/jwks.json"
token-uri: "https://oauth2.example.com/tokens"
registration:
client1:
provider: "myprovider"
client-id: "id-1"
client-secret: "secret-1"
authorization-grant-type: "authorization_code"
client2:
provider: "myprovider"
client-id: "id-2"
client-secret: "secret-2"
authorization-grant-type: "authorization_code"
这似乎是一个奇怪的疏忽(显然它在内部可供Spring Security使用),所以我不得不挠头,想知道我是否遗漏了一些明显的东西。
我以为我能写出这样的东西:
ClientRegistration registration = someObject.getClientRegistration();
String providerId = registration.getProviderId();
但是我找不到与上面的#getProviderId()
相当的东西,甚至是类似于ProviderRepository
bean的ClientRegistrationRepository
。
不幸的是,如果你看看Spring Boot自动配置,你会发现这些信息没有以任何方式保存。
看看OAuth2ClientPropertiesRegistrationAdapter
背后创建ClientRegistration
的逻辑。
String
都在使用您的配置填充的OAuth2ClientProperties.Registration
对象的字段中捕获。spring.security.oauth2.provider
中提供的提供者信息用于创建OAuth2ClientProperties.Provider
。但是,“providerId”不会保存在对象本身中(它无论如何都没有“providerId”或“providerName”字段)。相反,提供者名称/ id是Map<String,Provider>
中存在的OAuth2ClientProperties
的关键。ClientRegistration
时,String
中的提供者OAuth2ClientProperties.Registration
用于搜索地图。找到提供程序后,它将用于配置ClientRegistration.Builder
。这就是从OAuth2ClientProperties.Provider
获得的所有内容:
private static Builder getBuilder(Builder builder, Provider provider) {
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
map.from(provider::getAuthorizationUri).to(builder::authorizationUri);
map.from(provider::getTokenUri).to(builder::tokenUri);
map.from(provider::getUserInfoUri).to(builder::userInfoUri);
map.from(provider::getUserInfoAuthenticationMethod)
.as(AuthenticationMethod::new)
.to(builder::userInfoAuthenticationMethod);
map.from(provider::getJwkSetUri).to(builder::jwkSetUri);
map.from(provider::getUserNameAttribute)
.to(builder::userNameAttributeName);
return builder;
}
所以来自OAuth2ClientProperties.Registration
的“providerId”从未进入ClientRegistration
,而OAuth2ClientProperties.Provider
的“providerId”从未首先进入Provider
。你得到的最后是ClientRegistration
与ProviderDetails
...但没有“providerId”...