我们正面临Spring Security OAuth2(v 2.0.8)的问题 . 该应用程序是一个带有自定义身份验证管理器的Spring Boot应用程序(v 1.2.6),它使用JWT令牌而不是默认的随机值令牌 . 我们也使用Spring Cloud Angel.SR4并最终升级到Brixton,但目前我们“无法”转移到Spring Boot 1.3 .

应用程序使用默认的Spring Security配置参数来配置 Actuator endpoints 的安全性:

security.user.name:user
security.user.password:password

这是OAuth2配置的相关部分:

@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

  private AuthenticationManager oauthUserAuthenticationManager() {
    Collection<UserDetails> users = new LinkedList<>();
    users.add(new User("john", "doe", Arrays.asList(new SimpleGrantedAuthority("USER"))));
    users.add(new User("jane", "doe", Arrays.asList(new SimpleGrantedAuthority("USER"), new SimpleGrantedAuthority("ADMIN"))));
    UserDetailsManager manager = new InMemoryUserDetailsManager(users);
    DaoAuthenticationProvider p = new DaoAuthenticationProvider();
    p.setUserDetailsService(manager);
    return new ProviderManager(Arrays.asList(p));
  }

  @Bean
  public JwtAccessTokenConverter jwtAccessTokenConverter() {
    JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
    Resource fsr = resourceLoader.getResource(keystore);
    KeyPair keyPair = 
      new KeyStoreKeyFactory(fsr, keystorePassword.toCharArray())
        .getKeyPair(keyPairAlias, keyPairPassword.toCharArray());
    converter.setKeyPair(keyPair);
    return converter;
  }

  public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    endpoints
      .authenticationManager(oauthUserAuthenticationManager())
      .accessTokenConverter(jwtAccessTokenConverter());
  }
}

使用密码授权(grant_type =密码)时,应用程序正常工作,并且使用john / doe或jane / doe成功授予令牌 . 但是,在尝试使用刷新令牌授权(grant_type = refresh_token)时,会抛出异常: UsernameNotFoundException: john .

从调试我已经看到,当使用authenticationManager验证用户是否仍然存在时,错误始于 DefaultTokenServices.refreshAccessToken() (第150行):

user = authenticationManager.authenticate(user);

调试器还显示authenticationManager接受了用户名 user 的身份验证,因此看起来tokenServices使用默认身份验证管理器,密码令牌granter(ResourceOwnerPasswordTokenGranter)使用我们的配置中由AuthorizationServerEndpointsConfigurer配置的自定义身份验证管理器 .

我们认为我们需要做的是在两个地方配置相同的身份验证管理器,但是如何?