Spring OAuth2, требующий PlatformTransactionManager

Я работаю над интеграцией Spring Security OAuth2 с токенами JWT в проект Spring Boot. Мой сервер аутентификации настроен аналогично тому, что находится в этом пример проекта.

Когда клиент OAuth2 выполняет POST на /oauth/token, он не может создать токен доступа. Зарегистрирована конкретная ошибка:

o.s.s.o.provider.endpoint.TokenEndpoint : Handling error: NoSuchBeanDefinitionException, No qualifying bean of type [org.springframework.transaction.PlatformTransactionManager] is defined

Я отладил его до AbstractTokenGranter строки 70 при вызове tokenServices.createAccessToken. Я не смог легко отладить дальше, потому что этот вызов на самом деле проходит через прокси. Кажется, что-то в конфигурации хочет сделать это транзакционным. Создание токенов доступа не должно быть транзакционным в JWT. Я мог понять, почему получение кода доступа было бы транзакционным, но код успешно прошел эту точку.

Почему для этого может потребоваться PlatformTransactionManager и как я могу его предоставить?


person David V    schedule 01.07.2015    source источник


Ответы (4)


Проблема в том, что вы настроили в своем приложении использование базы данных в памяти с помощью new InMemoryTokenStore(), но ваше приложение с весенней загрузкой не содержит базы данных в памяти.

Решение: добавьте в зависимости от весенней загрузки pom или gradle базу данных в памяти.

Пример для H2 и Maven pom:

<dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <version>1.4.187</version>
</dependency>
person Florian E.    schedule 23.07.2015
comment
Спасибо за предложение, но я не использую базу данных SQL. - person David V; 29.07.2015
comment
Вопрос: Где вы храните зарегистрированных клиентов? - person Florian E.; 15.08.2015
comment
Еще одна подсказка для вас. Внутренняя реализация spring для службы DefaultTokenService по умолчанию аннотирована @Transactional (строка 81). Чем вам нужен любой менеджер транзакций. Я вижу два решения для вас. Реализуйте свой собственный TokenService без аннотации Transactional или добавьте в базу данных памяти в качестве зависимости. - person Florian E.; 15.08.2015
comment
Это не имеет ничего общего с предоставлением базы данных в памяти. Реализации Sprin Oauth InMemory используют карту для хранения ключей и значений. - person Daniel Cerecedo; 22.10.2015
comment
@ФлорианЭ. Я хотел бы хранить полномочия в отдельной таблице, но getAccessToken в DefaultTokenService не снабжен аннотацией @Transactional. Поэтому я получаю ленивые исключения инициализации, знаете ли вы, есть ли какая-либо причина не проксировать метод get? - person Tim; 06.01.2017

У меня такая же проблема

tokenServices.createAccessToken использует @Transactional . Поскольку я использую mongo DB, мне не нужны транзакции.

Я решил проблему, добавив bean-компонент PseudoTransactionManager.

@Bean
public PlatformTransactionManager annotationDrivenTransactionManager() {
    return new PseudoTransactionManager();
}
person Yassine Bsf    schedule 26.10.2017

Проблема в том, что методы в DefaultTokenServices аннотированы @Transactional. Таким образом, даже если вы не используете базу данных, вам необходимо добавить bean-компонент диспетчера транзакций, подобный этому, в конфигурацию вашего сервера авторизации:

    @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 {

            }
        };
    }
person Neets    schedule 26.10.2017

Я столкнулся с аналогичной проблемой PlatformTransactionManager и решил ее, выполнив следующие действия:

  1. Добавлена ​​база данных H2 в pom.xml (для возможности хранения клиентов в памяти)
  2. Использование Mongo DB в качестве серверной части приложения. (гарантированное приложение использует MongoRepository вместо CrudRepository)
  3. Удален класс исключения в аннотации @EnableAutoConfiguration (ранее я добавил DataSourceAutoConfiguration.class в исключение)

Пункт 1 и пункт 3 взаимны. В конфигурации H2 должен быть включен DataSourceAutoConfiguration.class.

Спасибо.

person DecKno    schedule 13.02.2017