问题
I'm working on integrating Spring Security OAuth2 with JWT tokens into a Spring Boot project. My authentication server is configured similar to what is found in this sample project.
When the OAuth2 client performs the POST on /oauth/token
it is unable to create the access token. The specific error logged is:
o.s.s.o.provider.endpoint.TokenEndpoint : Handling error: NoSuchBeanDefinitionException, No qualifying bean of type [org.springframework.transaction.PlatformTransactionManager] is defined
I've debugged it down to AbstractTokenGranter
line 70 at the call to tokenServices.createAccessToken
. I've not been able to easily debug further than that because this call actually goes through a proxy. It seems something in the configuration is wanting to make this transactional. Creating access tokens shouldn't be transactional in JWT. I could see why retrieving the access code would be transactional, but the code successfully gets past that point.
Why might this be requiring the PlatformTransactionManager
and how can I supply one?
回答1:
Problem is that you configured in your application a usage of a in-memory database with new InMemoryTokenStore()
, but your spring-boot application contains no in-memory database.
Solution: add in your spring-boot pom or gradle dependency a in-memory database.
Example for H2 and Maven pom:
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.187</version>
</dependency>
回答2:
I had the same problem
tokenServices.createAccessToken use @Transactional . As i use mongo DB i don't need transactions .
i solved the problem by adding a PseudoTransactionManager bean .
@Bean
public PlatformTransactionManager annotationDrivenTransactionManager() {
return new PseudoTransactionManager();
}
回答3:
The problem is that methods in DefaultTokenServices are annotated with @Transactional. So even if you're not using a database, you'll need to add a transaction manager bean like this in your authorization server configuration:
@Bean
public PlatformTransactionManager annotationDrivenTransactionManager() {
return new ResourceTransactionManager() {
@Override
public Object getResourceFactory() {
return null;
}
@Override
public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
return null;
}
@Override
public void commit(TransactionStatus status) throws TransactionException {
}
@Override
public void rollback(TransactionStatus status) throws TransactionException {
}
};
}
回答4:
I faced similar issue of PlatformTransactionManager and resolved it by the following steps:
- Added H2 database to
pom.xml
(to enable storage of clients in memory) - Using Mongo DB as application backend. (ensured application uses MongoRepository instead of CrudRepository)
- Removed exclude class in
@EnableAutoConfiguration
annotation (I had earlier addedDataSourceAutoConfiguration.class
in exclusion)
Point 1 and Point 3 are mutual. H2 configuration should have DataSourceAutoConfiguration.class enabled.
Thanks.
来源:https://stackoverflow.com/questions/31171418/spring-oauth2-requiring-platformtransactionmanager