将 Jdbc 数据存储分配给 ClientDetailsS​​ervice 时 Spring AuthorizationServerConfigurerAdapter 出错

error in Spring AuthorizationServerConfigurerAdapter when assigning Jdbc datastore to ClientDetailsService

您好,我正在使用 Spring Oauth2 创建 AuthorizationServerConfigurerAdapter 身份验证服务器。我选择了 JdbcTokenStore 并将 TokenStore 数据库设置为 OrientDb。

我是这样定义的clientDetailsService

@Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        // @formatter:off
        DataSource dataSource = DataSourceBuilder.create()
                .driverClassName("com.orientechnologies.orient.jdbc.OrientJdbcDriver")
                .url("jdbc:orient:remote:localhost/pricewiz").username("xxxxx").password("xxxxx").build();
        clients
            .jdbc(dataSource)
                .withClient("pricewiz")
                    .authorizedGrantTypes("password","refresh_token","implicit")
                    .authorities("USER")
                    .scopes("read", "write")
                    .resourceIds(RESOURCE_ID)
                    .secret("19800928100000");
        // @formatter:on
    }

我还定义了如下表格:

orientdb {db=pricewiz}> info class oauth_client_details

Class................: oauth_client_details
Default cluster......: oauth_client_details (id=19)
Supported cluster ids: [19]
Cluster selection....: round-robin

PROPERTIES
-------------------------------+-------------+-------------------------------+-----------+----------+----------+-----------+-----------+----------+
 NAME                          | TYPE        | LINKED TYPE/CLASS             | MANDATORY | READONLY | NOT NULL |    MIN    |    MAX    | COLLATE  |
-------------------------------+-------------+-------------------------------+-----------+----------+----------+-----------+-----------+----------+
 additional_information        | STRING      | null                          | false     | false    | false    |           |           | default  |
 autoapprove                   | STRING      | null                          | false     | false    | false    |           |           | default  |
 scope                         | STRING      | null                          | false     | false    | false    |           |           | default  |
 web_server_redirect_uri       | STRING      | null                          | false     | false    | false    |           |           | default  |
 authorized_grant_types        | STRING      | null                          | false     | false    | false    |           |           | default  |
 client_secret                 | STRING      | null                          | false     | false    | false    |           |           | default  |
 resource_ids                  | STRING      | null                          | false     | false    | false    |           |           | default  |
 authorities                   | STRING      | null                          | false     | false    | false    |           |           | default  |
 client_id                     | STRING      | null                          | false     | false    | true     |           |           | default  |
-------------------------------+-------------+-------------------------------+-----------+----------+----------+-----------+-----------+----------+
orientdb {db=pricewiz}> info class oauth_client_token

Class................: oauth_client_token
Default cluster......: oauth_client_token (id=20)
Supported cluster ids: [20]
Cluster selection....: round-robin

PROPERTIES
-------------------------------+-------------+-------------------------------+-----------+----------+----------+-----------+-----------+----------+
 NAME                          | TYPE        | LINKED TYPE/CLASS             | MANDATORY | READONLY | NOT NULL |    MIN    |    MAX    | COLLATE  |
-------------------------------+-------------+-------------------------------+-----------+----------+----------+-----------+-----------+----------+
 token_id                      | STRING      | null                          | false     | false    | false    |           |           | default  |
 user_name                     | STRING      | null                          | false     | false    | false    |           |           | default  |
 client_id                     | STRING      | null                          | false     | false    | false    |           |           | default  |
 authentication_id             | STRING      | null                          | false     | false    | false    |           |           | default  |
 token                         | BINARY      | null                          | false     | false    | false    |           |           | default  |
-------------------------------+-------------+-------------------------------+-----------+----------+----------+-----------+-----------+----------+
orientdb {db=pricewiz}> info class oauth_access_token

Class................: oauth_access_token
Default cluster......: oauth_access_token (id=21)
Supported cluster ids: [21]
Cluster selection....: round-robin

PROPERTIES
-------------------------------+-------------+-------------------------------+-----------+----------+----------+-----------+-----------+----------+
 NAME                          | TYPE        | LINKED TYPE/CLASS             | MANDATORY | READONLY | NOT NULL |    MIN    |    MAX    | COLLATE  |
-------------------------------+-------------+-------------------------------+-----------+----------+----------+-----------+-----------+----------+
 refresh_token                 | STRING      | null                          | false     | false    | false    |           |           | default  |
 token_id                      | STRING      | null                          | false     | false    | false    |           |           | default  |
 user_name                     | STRING      | null                          | false     | false    | false    |           |           | default  |
 authentication_id             | STRING      | null                          | false     | false    | false    |           |           | default  |
 client_id                     | STRING      | null                          | false     | false    | false    |           |           | default  |
 authentication                | BINARY      | null                          | false     | false    | false    |           |           | default  |
 token                         | BINARY      | null                          | false     | false    | false    |           |           | default  |
-------------------------------+-------------+-------------------------------+-----------+----------+----------+-----------+-----------+----------+
orientdb {db=pricewiz}> info class oauth_refresh_token

Class................: oauth_refresh_token
Default cluster......: oauth_refresh_token (id=22)
Supported cluster ids: [22]
Cluster selection....: round-robin

PROPERTIES
-------------------------------+-------------+-------------------------------+-----------+----------+----------+-----------+-----------+----------+
 NAME                          | TYPE        | LINKED TYPE/CLASS             | MANDATORY | READONLY | NOT NULL |    MIN    |    MAX    | COLLATE  |
-------------------------------+-------------+-------------------------------+-----------+----------+----------+-----------+-----------+----------+
 token_id                      | STRING      | null                          | false     | false    | false    |           |           | default  |
 token                         | BINARY      | null                          | false     | false    | false    |           |           | default  |
 authentication                | BINARY      | null                          | false     | false    | false    |           |           | default  |
-------------------------------+-------------+-------------------------------+-----------+----------+----------+-----------+-----------+----------+
orientdb {db=pricewiz}> info class oauth_code

Class................: oauth_code
Default cluster......: oauth_code (id=23)
Supported cluster ids: [23]
Cluster selection....: round-robin

PROPERTIES
-------------------------------+-------------+-------------------------------+-----------+----------+----------+-----------+-----------+----------+
 NAME                          | TYPE        | LINKED TYPE/CLASS             | MANDATORY | READONLY | NOT NULL |    MIN    |    MAX    | COLLATE  |
-------------------------------+-------------+-------------------------------+-----------+----------+----------+-----------+-----------+----------+
 code                          | STRING      | null                          | false     | false    | false    |           |           | default  |
 authentication                | BINARY      | null                          | false     | false    | false    |           |           | default  |
-------------------------------+-------------+-------------------------------+-----------+----------+----------+-----------+-----------+----------+
orientdb {db=pricewiz}> info class oauth_approvals

Class................: oauth_approvals
Default cluster......: oauth_approvals (id=24)
Supported cluster ids: [24]
Cluster selection....: round-robin

PROPERTIES
-------------------------------+-------------+-------------------------------+-----------+----------+----------+-----------+-----------+----------+
 NAME                          | TYPE        | LINKED TYPE/CLASS             | MANDATORY | READONLY | NOT NULL |    MIN    |    MAX    | COLLATE  |
-------------------------------+-------------+-------------------------------+-----------+----------+----------+-----------+-----------+----------+
 clientId                      | STRING      | null                          | false     | false    | false    |           |           | default  |
 scope                         | STRING      | null                          | false     | false    | false    |           |           | default  |
 userId                        | STRING      | null                          | false     | false    | false    |           |           | default  |
 lastModifiedAt                | DATE        | null                          | false     | false    | false    |           |           | default  |
 expiresAt                     | DATE        | null                          | false     | false    | false    |           |           | default  |
 status                        | STRING      | null                          | false     | false    | false    |           |           | default  |
-------------------------------+-------------+-------------------------------+-----------+----------+----------+-----------+-----------+----------+
orientdb {db=pricewiz}>

现在,当我尝试使用 curl 获取身份验证密钥时,出现以下错误:

{"timestamp":1420109129595,"status":401,"error":"Unauthorized","message":"Error creating bean with name 'scopedTarget.clientDetailsService' defined in class path resource [org/springframework/security/oauth2/config/annotation/configuration/ClientDetailsServiceConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.oauth2.provider.ClientDetailsService]: Factory method 'clientDetailsService' threw exception; nested exception is java.lang.ClassCastException: com.orientechnologies.orient.core.record.impl.ODocument cannot be cast to java.lang.Integer"}

请帮忙,因为我是 Spring 安全方面的新手。

谢谢, 努鲁尔

编辑

我尝试按照建议使用 MariaDB,并将 OAuth 部分移动到 XML 文件中。

spring-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
       xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:sec="http://www.springframework.org/schema/security"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
       <http pattern="/oauth/token" create-session="stateless"
             authentication-manager-ref="authenticationManager"
             xmlns="http://www.springframework.org/schema/security" >
              <intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
              <anonymous enabled="false" />
              <http-basic entry-point-ref="clientAuthenticationEntryPoint"/>
              <custom-filter ref="clientCredentialsTokenEndpointFilter"         before="BASIC_AUTH_FILTER" />
              <access-denied-handler ref="oauthAccessDeniedHandler" />
       </http>
       <bean id="clientCredentialsTokenEndpointFilter"
             class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
              <property name="authenticationManager" ref="authenticationManager" />
       </bean>

       <authentication-manager alias="authenticationManager"
                               xmlns="http://www.springframework.org/schema/security">
              <authentication-provider user-service-ref="clientDetailsUserService" />
       </authentication-manager>
       <bean id="clientDetailsUserService"
             class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
              <constructor-arg ref="clientDetails" />
       </bean>
       <bean id="clientDetails" class="com.rayat.pricewizWS.security.ClientDetailsServiceImpl"></bean>
       <bean id="clientAuthenticationEntryPoint"
             class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
              <property name="realmName" value="springsec/client" />
              <property name="typeName" value="Basic" />
       </bean>
       <bean id="oauthAccessDeniedHandler"
             class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler"/>

       <oauth:authorization-server
               client-details-service-ref="clientDetails" token-services-ref="tokenServices">
              <oauth:authorization-code />
              <oauth:implicit/>
              <oauth:refresh-token/>
              <oauth:client-credentials />
              <oauth:password authentication-manager-ref="userAuthenticationManager"/>
       </oauth:authorization-server>

       <authentication-manager id="userAuthenticationManager"
                               xmlns="http://www.springframework.org/schema/security">
              <authentication-provider  ref="customUserAuthenticationProvider">
              </authentication-provider>
       </authentication-manager>
       <bean id="customUserAuthenticationProvider"
             class="com.rayat.pricewizWS.security.CustomUserAuthenticationProvider">
       </bean>

       <bean id="tokenServices"
             class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
              <property name="tokenStore" ref="tokenStore" />
              <property name="supportRefreshToken" value="true" />
              <property name="accessTokenValiditySeconds" value="900000000"></property>
              <property name="clientDetailsService" ref="clientDetails" />
       </bean>
       <bean id="tokenStore"
             class="org.springframework.security.oauth2.provider.token.store.JdbcTokenStore">
           <constructor-arg ref="mariadbJdbcTemplate"/>
       </bean>
       <bean id="mariadbJdbcTemplate"
             class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
            <property name="driverClassName" value="org.mariadb.jdbc.Driver"/>
            <property name="url" value="jdbc:mariadb://localhost:3306/oauthdb"/>
            <property name="username" value="root"/>
            <property name="password" value="xxxxxxxx"/>
       </bean>
        <bean id="orientDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="com.orientechnologies.orient.jdbc.OrientJdbcDriver"/>
            <property name="url" value="jdbc:orient:remote:localhost/pricewiz"/>
            <property name="username" value="admin"/>
            <property name="password" value="xxxxxxxx"/>
        </bean>
       <bean id="oauthAuthenticationEntryPoint"
             class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
       </bean>
       <http pattern="/product/**" create-session="never"
             entry-point-ref="oauthAuthenticationEntryPoint"
             xmlns="http://www.springframework.org/schema/security">
              <anonymous enabled="false" />
              <intercept-url pattern="/product/**"  access="IS_AUTHENTICATED_FULLY" />
              <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
              <access-denied-handler ref="oauthAccessDeniedHandler" />
       </http>
       <oauth:resource-server id="resourceServerFilter"
                              resource-id="springsec" token-services-ref="tokenServices" />
       <http pattern="/logout" create-session="never" entry-point-ref="oauthAuthenticationEntryPoint"
             xmlns="http://www.springframework.org/schema/security">
              <anonymous enabled="false" />
              <intercept-url pattern="/logout" access="ROLE_CLIENT" method="GET" />
              <sec:logout invalidate-session="true" logout-url="/logout" success-handler-ref="logoutSuccessHandler"/>
              <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
              <access-denied-handler ref="oauthAccessDeniedHandler" />
       </http>
       <bean id="logoutSuccessHandler"
             class="com.rayat.pricewizWS.security.LogoutImpl" >
              <property name="tokenstore" ref="tokenStore"></property>
       </bean>
</beans>

现在,当我尝试在 tomcat 上启动时,出现以下错误:

Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath.
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:558)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)

你能告诉我现在的问题是什么吗?

谢谢, 努鲁尔

我对 orientdb 了解不多,但是所有这些 "STRING" 类型看起来都有点不对(错误提示您有一列类型错误)。这里有一些 DDL 可以开始(至少使用普通的 SQL 数据库):https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/test/resources/schema.sql。你为什么不先尝试不同的数据库来让它工作?