spring oauth2 中带有自定义 ClientDetailsService 的 StackOverflowError
StackOverflowError in spring oauth2 with custom ClientDetailsService
我自己实现了 ClientDetailsService:
@Service
public class JpaClientDetailsService implements ClientDetailsService {
@Autowired
private ClientRepository clientRepositoy;
@Override
public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
ClientDetails client = clientRepositoy.findOne(clientId);
if (client == null) {
throw new ClientRegistrationException(String.format("Client with id %s not found", clientId));
}
return client;
}
}
ClientRepository 是一个标准的 JpaRepository。
我这样配置了一个 AuthorizationServerConfigurerAdapter:
@Configuration
@EnableAuthorizationServer
@EnableResourceServer
public class OAuth2ServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private ClientDetailsService clientDetailsService;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService);
}
}
但是当我去 http://localhost:9999/oauth/authorize?response_type=code&client_id=lipton
时,我得到一个
java.lang.WhosebugError: null. Spring loops on com.sun.proxy.$Proxy81.loadClientByClientId(Unknown Source).
我不明白为什么。
我不明白为什么,但是如果我直接注入我的 bean 而不是注入接口,它就可以工作:
public class OAuth2ServerConfig extends AuthorizationServerConfigurerAdapter {
...
@Autowired
private JpaClientDetailsService clientDetailsService;
...
如果我用@Primary 注释来注释我的服务,它也可以工作:
@Service
@Primary
public class JpaClientDetailsService implements ClientDetailsService {
我遇到了类似的问题。最后我解决了错误,当我给我的 clientDetailsService 另一个名字,即 myClientDetailsService 然后在 AuthorizationServerConfig class:
中按名称注入这个
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Resource(name = "myClientDetailsService")
private ClientDetailsService clientDetailsService;
...
我认为如果我自己的 ClientDetailsService 实现尚未创建 Spring 将某种代理注入 AuthorizationServerConfig。
因此,如果您想解决此类错误,您必须确保
Spring 在中注入正确的 ClientDetailsService
授权服务器配置。如果您:
,您可以实现这一目标
- 提供 spring 有关您自己的 ClientDetailsService 偏好的信息(Arnaud 回答),或
- 按名称注入此服务
最终对我有用的是将 ClientDetailsService @Bean 添加到 @EnableAuthorizationServer class:
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration implements AuthorizationServerConfigurer {
...
@Autowired
ClientDetailsService clientDetailsService;
...
@Bean
public ClientDetailsService clientDetailsService() {
return new CustomClientDetailsServiceImpl();
}
...
}
我会说最好的解决方案是明确的 - 如果你正在自动装配 clientDetailsService - 那么就这样说。
@Autowired
ClientDetailsService myClientDetailsService;
@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.setClientDetailsService(myClientDetailsService);
....
}
但是,我的问题略有不同,上述解决方案均无效。这是创造它的条件。
我创建了一个 CustomTokenEndpointAuthenticationFilter - 它需要一个 OAuth2RequestFactory 实例。
我通过调用 endpoints.getOAuth2RequestFactory(); 创建了我的 OAuth2RequestFactory 实例;在设置 clientDetailsService 之前。
如果以这种方式创建 OAuth2RequestFactory,则会使用默认的 clientDetailsService 创建 DefaultOAuth2RequestFactory,因此即使您稍后在 AuthorizationServerEndpointsConfigurer 中明确设置 clientDetailsService,它也不会出现在您的自定义过滤器使用的 OAuth2RequestFactory 中。
总而言之,在这种极端情况下
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
oAuth2RequestFactory = endpoints.getOAuth2RequestFactory();
endpoints.setClientDetailsService(myClientDetailsService);
...
}
不会工作但是
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.setClientDetailsService(myClientDetailsService);
oAuth2RequestFactory = endpoints.getOAuth2RequestFactory();
...
}
会。
另一种确定的方法是创建您自己的 OAuth2RequestFatory
oauth2RequestFactory = new DefaultTokenRequestFactory(myClientDetailsService);
我修复了在我的 costum ClientDetailsService 中注释 @Primary 的问题:
@Service
@Primary
public class ClientDetailsServiceImp implements ClientDetailsService {
我自己实现了 ClientDetailsService:
@Service
public class JpaClientDetailsService implements ClientDetailsService {
@Autowired
private ClientRepository clientRepositoy;
@Override
public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
ClientDetails client = clientRepositoy.findOne(clientId);
if (client == null) {
throw new ClientRegistrationException(String.format("Client with id %s not found", clientId));
}
return client;
}
}
ClientRepository 是一个标准的 JpaRepository。
我这样配置了一个 AuthorizationServerConfigurerAdapter:
@Configuration
@EnableAuthorizationServer
@EnableResourceServer
public class OAuth2ServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private ClientDetailsService clientDetailsService;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService);
}
}
但是当我去 http://localhost:9999/oauth/authorize?response_type=code&client_id=lipton
时,我得到一个
java.lang.WhosebugError: null. Spring loops on com.sun.proxy.$Proxy81.loadClientByClientId(Unknown Source).
我不明白为什么。
我不明白为什么,但是如果我直接注入我的 bean 而不是注入接口,它就可以工作:
public class OAuth2ServerConfig extends AuthorizationServerConfigurerAdapter {
...
@Autowired
private JpaClientDetailsService clientDetailsService;
...
如果我用@Primary 注释来注释我的服务,它也可以工作:
@Service
@Primary
public class JpaClientDetailsService implements ClientDetailsService {
我遇到了类似的问题。最后我解决了错误,当我给我的 clientDetailsService 另一个名字,即 myClientDetailsService 然后在 AuthorizationServerConfig class:
中按名称注入这个@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Resource(name = "myClientDetailsService")
private ClientDetailsService clientDetailsService;
...
我认为如果我自己的 ClientDetailsService 实现尚未创建 Spring 将某种代理注入 AuthorizationServerConfig。
因此,如果您想解决此类错误,您必须确保 Spring 在中注入正确的 ClientDetailsService 授权服务器配置。如果您:
,您可以实现这一目标- 提供 spring 有关您自己的 ClientDetailsService 偏好的信息(Arnaud 回答),或
- 按名称注入此服务
最终对我有用的是将 ClientDetailsService @Bean 添加到 @EnableAuthorizationServer class:
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration implements AuthorizationServerConfigurer {
...
@Autowired
ClientDetailsService clientDetailsService;
...
@Bean
public ClientDetailsService clientDetailsService() {
return new CustomClientDetailsServiceImpl();
}
...
}
我会说最好的解决方案是明确的 - 如果你正在自动装配 clientDetailsService - 那么就这样说。
@Autowired
ClientDetailsService myClientDetailsService;
@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.setClientDetailsService(myClientDetailsService);
....
}
但是,我的问题略有不同,上述解决方案均无效。这是创造它的条件。 我创建了一个 CustomTokenEndpointAuthenticationFilter - 它需要一个 OAuth2RequestFactory 实例。 我通过调用 endpoints.getOAuth2RequestFactory(); 创建了我的 OAuth2RequestFactory 实例;在设置 clientDetailsService 之前。
如果以这种方式创建 OAuth2RequestFactory,则会使用默认的 clientDetailsService 创建 DefaultOAuth2RequestFactory,因此即使您稍后在 AuthorizationServerEndpointsConfigurer 中明确设置 clientDetailsService,它也不会出现在您的自定义过滤器使用的 OAuth2RequestFactory 中。
总而言之,在这种极端情况下
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
oAuth2RequestFactory = endpoints.getOAuth2RequestFactory();
endpoints.setClientDetailsService(myClientDetailsService);
...
}
不会工作但是
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.setClientDetailsService(myClientDetailsService);
oAuth2RequestFactory = endpoints.getOAuth2RequestFactory();
...
}
会。
另一种确定的方法是创建您自己的 OAuth2RequestFatory
oauth2RequestFactory = new DefaultTokenRequestFactory(myClientDetailsService);
我修复了在我的 costum ClientDetailsService 中注释 @Primary 的问题:
@Service
@Primary
public class ClientDetailsServiceImp implements ClientDetailsService {