Hi I am creating the AuthorizationServerConfigurerAdapter
authentication server with Spring Oauth2. I have selected JdbcTokenStore and set the TokenStore database as OrientDb.
Here is how I am defining 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
}
I also defined the tables as follows:
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}>
Now, when I am trying to obtain the authentication key using curl, it gives me the following error:
{"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"}
Please help as I am new to Spring Security.
Thanks, Noorul
Edit
I tried using MariaDB as per suggestion and moved the OAuth part in the XML file.
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>
Now, when I try to launch on tomcat, I am getting the following error:
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)
Could you please let me know what is the problem now.
Thanks, Noorul
I don't really know much about orientdb, but all those "STRING" types look a bit wrong (and the error suggests you have a column of the wrong type). There is some DDL to get started (at least with a normal SQL database) here: https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/test/resources/schema.sql. Why don't you try different database first to get it working?