spring security oauth2 ClassCastException 配置 DefaultTokenServices

spring security oauth2 ClassCastException configuring DefaultTokenServices

我正在尝试 运行 使用 spring 引导和 spring 安全 oauth 的示例应用程序,其中配置了 JdbcTokenStore 和具有无限生命周期访问令牌的 DefaultTokenServices。

运行 此应用程序使用 gradle bootRun,应用程序无法启动并抛出 "Caused by: java.lang.ClassCastException: com.sun.proxy.$Proxy51 cannot be cast to org.springframework.security.oauth2.provider.token.DefaultTokenServices"

为什么 DefaultTokenServices bean 周围有一个代理?

奇怪的是 - 运行使用 InMemoryTokenStore 连接应用程序...一切正常(参见内存分支)。

源代码https://github.com/grafjo/oauth_demo/blob/master/src/main/java/demo/AuthorizationServerConfiguration.java

完整跟踪:http://pastebin.com/SUcwz4S5

我的应用程序中也有类似的异常,当将 spring oauth 版本从 2.0.7.RELEASE 更改为 2.0.3.RELEASE 时,它起作用了。也许这是最新版本中的错误?

编辑: 从错误看来问题与 spring 创建的代理有关。当我将代理类型更改为 CGLIB 而不是默认动态代理时,它也适用于 2.0.7 版。这个设置可以通过 proxyTargetClass 属性 @EnableTransactionManagement(proxyTargetClass = true)

来设置

但是这个解决方案对我没有吸引力,因为我更喜欢默认代理方法而不是 CGLIB。这里还有一篇解释代理方法的文章http://thecafetechno.com/tutorials/spring/spring-proxying-mechanisms/

快速浏览一下 DefaultTokenService 就会发现它带有 @Transactional 注释。 Spring 将把它包装在一个代理中来为交易提供服务 - 因此您需要通过其接口与 class 进行交互。

对于您的 tokenService bean:

@Bean
public DefaultTokenServices tokenServices() {
    final DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
    defaultTokenServices.setAccessTokenValiditySeconds(-1);
    defaultTokenServices.setTokenStore(tokenStore());
    return defaultTokenServices;
}

尝试将其更改为:

@Bean
public AuthorizationServerTokenServices tokenServices() {
    final DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
    defaultTokenServices.setAccessTokenValiditySeconds(-1);
    defaultTokenServices.setTokenStore(tokenStore());
    return defaultTokenServices;
}

这适用于 2.0 版。7.RELEASE

 @Primary
 @Bean
 protected AuthorizationServerTokenServices tokenServices() throws Exception{

将 DefaultTokenServices 更改为 AuthorizationServerTokenServices 后,Spring 将抛出错误:

No qualifying bean of type [org.springframework.security.oauth2.provider.token.ResourceServerTokenServices] is defined: expected single matching bean but found 3: defaultAuthorizationServerTokenServices,consumerTokenServices,tokenServices"}}

我在以下组合中使用 2.0.9.RELEASE 时遇到了同样的问题:

pom.xml:

...    
<spring.version>4.1.4.RELEASE</spring.version>       
<spring-security.version>3.2.5.RELEASE</spring-security.version>
<spring-security-oauth2.version>2.0.9.RELEASE</spring-security-oauth2.version>
...

并有相同的异常。

降级到

...
<spring-security-oauth2.version>2.0.3.RELEASE</spring-security-oauth2.version>
...

为我解决了问题。

添加

<aop:config proxy-target-class="true"/> 

在您的 spring 配置上。