问题 Spring oauth2中的StackOverflowError,带有自定义ClientDetailsS​​ervice


我自己实现了ClientDetailsS​​ervice:

@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.StackOverflowError: null. Spring loops on com.sun.proxy.$Proxy81.loadClientByClientId(Unknown Source).

我不明白为什么。


7882
2017-08-04 00:00


起源



答案:


我不明白为什么,但如果我直接注入我的bean而不是注入接口,它的工作原理如下:

public class OAuth2ServerConfig extends AuthorizationServerConfigurerAdapter {
...
  @Autowired
  private JpaClientDetailsService clientDetailsService;
...

如果我用@Primary注释注释我的服务,它也有效:

@Service
@Primary
public class JpaClientDetailsService implements ClientDetailsService {

8
2017-08-04 23:44



我有同样的问题,并在添加后 @Primary 有用。我在这里看到的唯一原因是Spring上下文已经有了 ClientDetailsService bean并没有能够选择正确的bean - nanachimi


答案:


我不明白为什么,但如果我直接注入我的bean而不是注入接口,它的工作原理如下:

public class OAuth2ServerConfig extends AuthorizationServerConfigurerAdapter {
...
  @Autowired
  private JpaClientDetailsService clientDetailsService;
...

如果我用@Primary注释注释我的服务,它也有效:

@Service
@Primary
public class JpaClientDetailsService implements ClientDetailsService {

8
2017-08-04 23:44



我有同样的问题,并在添加后 @Primary 有用。我在这里看到的唯一原因是Spring上下文已经有了 ClientDetailsService bean并没有能够选择正确的bean - nanachimi


我有类似的问题。最后,当我向clientDetailsS​​ervice提供另一个名称,即myClientDetailsS​​ervice,然后在AuthorizationServerConfig类中按名称注入时,我解决了错误:

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Resource(name = "myClientDetailsService")
    private ClientDetailsService clientDetailsService;
...

我认为如果我自己的ClientDetailsS​​ervice实现还没有创建Spring注入AuthorizationServerConfig某种代理。

所以,如果你想解决这种错误,你一定要确定     Spring注入了适当的ClientDetailsS​​ervice     AuthorizationServerConfig。如果您:

  1. 提供有关您自己的ClientDetailsS​​ervice(Arnaud答案)的偏好的弹簧信息,或
  2. 按名称注入此服务

6
2018-01-21 17:26



也为我工作,我无法相信错误不是春天更好处理,所以vauge ... - bitsofinfo


最终为我工作的是将ClientDetailsS​​ervice @Bean添加到@EnableAuthorizationServer类:

@Configuration @EnableAuthorizationServer public class AuthorizationServerConfiguration implements AuthorizationServerConfigurer { ... @Autowired ClientDetailsService clientDetailsService; ... @Bean public ClientDetailsService clientDetailsService() { return new CustomClientDetailsServiceImpl(); } ... }


2
2017-10-04 17:58





我想说最好的解决方案是明确的 - 如果你是自动装载clientDetailsS​​ervice - 然后这样说。

@Autowired
ClientDetailsService myClientDetailsService;

@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {

        endpoints.setClientDetailsService(myClientDetailsService);
       ....
}

但是,我的问题略有不同,上述解决方案无效。以下是创建它的条件。 我创建了一个CustomTokenEndpointAuthenticationFilter - 它需要一个OAuth2RequestFactory实例。 我通过调用endpoints.getOAuth2RequestFactory()创建了我的OAuth2RequestFactory实例;在设置clientDetailsS​​ervice之前。

如果以这种方式创建OAuth2RequestFactory,则使用默认的clientDetailsS​​ervice创建DefaultOAuth2RequestFactory,因此即使稍后在AuthorizationServerEndpointsConfigurer中显式设置clientDetailsS​​ervice,它也不会位于自定义Filter使用的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);

0
2017-08-13 01:28