In Mule EE 3.8.5 I am getting a ClassCastException when loading an oauth2 access token. I'm using mule-module-security-oauth2-provider version 1.7.2 and mule-module-objectstore 2.1.0
The stracktrace starts:
java.lang.ClassCastException: java.lang.String cannot be cast to org.mule.modules.oauth2.provider.token.AccessTokenStoreHolder
at org.mule.modules.oauth2.provider.token.ObjectStoreTokenStore.retrieveByAccessToken(ObjectStoreTokenStore.java:38)
at org.mule.modules.oauth2.provider.token.TokenManager.getNonExpiredAccessTokenHolder(TokenManager.java:116)
at org.mule.modules.oauth2.provider.OAuth2ProviderModule.validate(OAuth2ProviderModule.java:543)
at org.mule.modules.oauth2.provider.processors.ValidateMessageProcessor$1.process(ValidateMessageProcessor.java:178)
at org.mule.modules.oauth2.provider.adapters.OAuth2ProviderModuleProcessAdapter$1.execute(OAuth2ProviderModuleProcessAdapter.java:36)
at org.mule.modules.oauth2.provider.processors.ValidateMessageProcessor.doProcess(ValidateMessageProcessor.java:164)
My config has the token stored successfully into a simple H2 database table of the form:
create table ACCESSTOKENOBJECTSTORE (k varchar(1000), v varchar(1000000))
I can see the tokens being created in this table, but I get the ClassCastException when trying to validate the token. My flow looks like:
<?xml version="1.0" encoding="UTF-8"?>
http://www.mulesoft.org/schema/mule/ee/jdbc/current/mule-jdbc-ee.xsd http://www.mulesoft.org/schema/mule/oauth2 http://www.mulesoft.org/schema/mule/oauth2/current/mule-oauth2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd http://www.mulesoft.org/schema/mule/oauth2-provider http://www.mulesoft.org/schema/mule/oauth2-provider/current/mule-oauth2-provider.xsd http://www.mulesoft.org/schema/mule/api-platform-gw http://www.mulesoft.org/schema/mule/api-platform-gw/current/mule-api-platform-gw.xsd http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd http://www.mulesoft.org/schema/mule/cors http://www.mulesoft.org/schema/mule/cors/current/mule-cors.xsd http://www.mulesoft.org/schema/mule/spring-security http://www.mulesoft.org/schema/mule/spring-security/current/mule-spring-security.xsd http://www.mulesoft.org/schema/mule/objectstore http://www.mulesoft.org/schema/mule/objectstore/current/mule-objectstore.xsd">
<spring:beans>
<spring:bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"
name="dataSource">
<spring:property name="jdbcUrl"
value="jdbc:h2:tcp://localhost/~/h2/h2db" />
<spring:property name="username" value="sa" />
<spring:property name="password" value="sa" />
</spring:bean>
<spring:bean name="accessTokenJdbcStore"
class="org.mule.transport.jdbc.store.JdbcObjectStore">
<spring:property name="jdbcConnector" ref="accessTokenJdbcConnector"></spring:property>
<spring:property name="insertQueryKey" value="insertQueryKey"></spring:property>
<spring:property name="selectQueryKey" value="selectQueryKey"></spring:property>
<spring:property name="deleteQueryKey" value="deleteQueryKey"></spring:property>
<spring:property name="clearQueryKey" value="clearQueryKey"></spring:property>
</spring:bean>
<spring:bean name="refreshTokenJdbcStore"
class="org.mule.transport.jdbc.store.JdbcObjectStore">
<spring:property name="jdbcConnector" ref="refreshTokenJdbcConnector"></spring:property>
<spring:property name="insertQueryKey" value="insertQueryKey"></spring:property>
<spring:property name="selectQueryKey" value="selectQueryKey"></spring:property>
<spring:property name="deleteQueryKey" value="deleteQueryKey"></spring:property>
<spring:property name="clearQueryKey" value="clearQueryKey"></spring:property>
</spring:bean>
<spring:bean name="tokenStore"
class="org.mule.modules.oauth2.provider.token.ObjectStoreTokenStore">
<spring:property name="refreshTokenObjectStore" ref="refreshTokenJdbcStore" />
<spring:property name="accessTokenObjectStore" ref="accessTokenJdbcStore" />
</spring:bean>
</spring:beans>
<jdbc-ee:connector name="refreshTokenJdbcConnector"
pollingFrequency="1000" dataSource-ref="dataSource"
transactionPerMessage="false" doc:name="Database">
<jdbc-ee:query key="insertQueryKey"
value="insert into REFRESHTOKENOBJECTSTORE (k,v) values (?,?)"></jdbc-ee:query>
<jdbc-ee:query key="selectQueryKey"
value="select k,v from REFRESHTOKENOBJECTSTORE where k = ?"></jdbc-ee:query>
<jdbc-ee:query key="deleteQueryKey"
value="delete from REFRESHTOKENOBJECTSTORE where k = ?"></jdbc-ee:query>
<jdbc-ee:query key="clearQueryKey" value="delete from REFRESHTOKENOBJECTSTORE"></jdbc-ee:query>
</jdbc-ee:connector>
<jdbc-ee:connector name="accessTokenJdbcConnector"
pollingFrequency="1000" dataSource-ref="dataSource"
transactionPerMessage="false" doc:name="Database">
<jdbc-ee:query key="insertQueryKey"
value="insert into ACCESSTOKENOBJECTSTORE (k,v) values (?,?)"></jdbc-ee:query>
<jdbc-ee:query key="selectQueryKey"
value="select k,v from ACCESSTOKENOBJECTSTORE where k = ?"></jdbc-ee:query>
<jdbc-ee:query key="deleteQueryKey"
value="delete from ACCESSTOKENOBJECTSTORE where k = ?"></jdbc-ee:query>
<jdbc-ee:query key="clearQueryKey" value="delete from ACCESSTOKENOBJECTSTORE"></jdbc-ee:query>
</jdbc-ee:connector>
<objectstore:config name="accessTokenObjectStore"
objectStore-ref="accessTokenJdbcStore"></objectstore:config>
<objectstore:config name="refreshTokenObjectStore"
objectStore-ref="refreshTokenJdbcStore"></objectstore:config>
<oauth2-provider:config name="OAuth_provider_module"
accessTokenEndpointPath="oauth/token" providerName="CustomProvider"
authorizationEndpointPath="oauth/authorize" listenerConfig-ref="HTTP_Listener_Configuration"
supportedGrantTypes="CLIENT_CREDENTIALS" doc:name="OAuth provider module"
scopes="SOMETHING" enableRefreshToken="true" tokenStore-ref="tokenStore">
<oauth2-provider:clients>
<oauth2-provider:client clientId="abc" secret="def"
type="CONFIDENTIAL">
<oauth2-provider:authorized-grant-types>
<oauth2-provider:authorized-grant-type>CLIENT_CREDENTIALS</oauth2-provider:authorized-grant-type>
</oauth2-provider:authorized-grant-types>
<oauth2-provider:scopes>
<oauth2-provider:scope>SOMETHING</oauth2-provider:scope>
</oauth2-provider:scopes>
</oauth2-provider:client>
</oauth2-provider:clients>
</oauth2-provider:config>
<http:listener-config name="HTTP_Listener_Configuration"
host="0.0.0.0" port="8081" doc:name="HTTP Listener Configuration" />
<flow name="oauthFlow">
<http:listener config-ref="HTTP_Listener_Configuration"
doc:name="HTTP" path="/api" />
<oauth2-provider:validate config-ref="OAuth_provider_module"
doc:name="OAuth provider module" scopes="SOMETHING" />
<custom-processor
class="com.mulesoft.module.oauth2.ValidatorResponseBuilder" doc:name="Java" />
</flow>
Update:
A blob type would be more suitable for the v column. However for the DB2 driver that results in:
Caused by: java.sql.SQLException: [jcc][1091][10824][4.13.127] Invalid data conversion: Parameter instance org.mule.modules.oauth2.provider.token.AccessTokenStoreHolder@4ca9421d is invalid for the requested conversion. ERRORCODE=-4461, SQLSTATE=42815 Query: insert into ACCESSTOKENOBJECTSTORE (k,v) values (?,?) Parameters: [934GcogFNLR6U6r9uFYa4ABwyYY7CU-O5UP966_38T-Q0JqssQf_ZZWg-tF73jgMoDTUqoPcXD9HT1bYBMvLyQ, org.mule.modules.oauth2.provider.token.AccessTokenStoreHolder@4ca9421d]
at org.apache.commons.dbutils.QueryRunner.rethrow(QueryRunner.java:540) ~[commons-dbutils-1.2.jar:1.2]
at org.apache.commons.dbutils.QueryRunner.update(QueryRunner.java:597) ~[commons-dbutils-1.2.jar:1.2]
at org.apache.commons.dbutils.QueryRunner.update(QueryRunner.java:653) ~[commons-dbutils-1.2.jar:1.2]
at org.mule.transport.jdbc.store.JdbcObjectStore$2.process(JdbcObjectStore.java:205) ~[mule-transport-jdbc-3.8.5.jar:3.8.5]