首页 > 解决方案 > Oauth2 Spring-boot只读连接错误

问题描述

我不断收到错误消息,我确实使用@EnableTransactionManagement启用了事务,但在DefaultTokenServices中仍然没有调用事务。

任何帮助都感激不尽

注意:它正在使用 spring-boot 1.5,最近我升级到 2.1

2020-11-19 18:27:12.385 ERROR 49065 [tomcat-exec-2] - o.s.s.o.provider.endpoint.TokenEndpoint  : Handling error: TransientDataAccessResourceException, PreparedStatementCallback; SQL [insert into oauth_access_token (token_id, token, authentication_id, user_name, client_id, authentication, refresh_token) values (?, ?, ?, ?, ?, ?, ?)]; Connection is read-only. Queries leading to data modification are not allowed; nested exception is java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed

org.springframework.dao.TransientDataAccessResourceException: PreparedStatementCallback; SQL [insert into oauth_access_token (token_id, token, authentication_id, user_name, client_id, authentication, refresh_token) values (?, ?, ?, ?, ?, ?, ?)]; Connection is read-only. Queries leading to data modification are not allowed; nested exception is java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed
    at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:110)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)

标签: javaspringspring-bootspring-oauth2

解决方案


  1. 解决方案

我可以通过手动将事务附加到 oauth jdbctokenservice 来修复 hack。

 private static final String AOP_POINTCUT_EXPRESSION = "execution (* org.springframework.security.oauth2.provider.token.store.JdbcTokenStore.*(..))";

    @Autowired
    public void txAdvice(TransactionInterceptor txAdvice) throws NoSuchMethodException {
        DefaultTransactionAttribute required = new DefaultTransactionAttribute();
        MethodMapTransactionAttributeSource source = new MethodMapTransactionAttributeSource();
        final Method method = JdbcTokenStore.class.getMethod("storeAccessToken", OAuth2AccessToken.class, OAuth2Authentication.class);
        source.addTransactionalMethod(method, required);
        txAdvice.setTransactionAttributeSource(source);
    }

    @Bean
    public Advisor txAdviceAdvisor(TransactionInterceptor txAdvice) {
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
        return new DefaultPointcutAdvisor(pointcut, txAdvice);
    }

我还创建了 spring-security-oauth 的问题,但似乎它不应该支持 spring-boot 2.x。

任何聪明的人都想帮助了解为什么在 DefaultTokenServices 中没有调用 Transaction。

  1. 解决方案

为 DefaultTokenServices 创建 Bean 并将其传递给配置器

@Autowired
        private DefaultTokenServices tokenServices;

@Bean
        @Primary
        public DefaultTokenServices defaultTokenServices() {
            DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
            defaultTokenServices.setTokenStore(tokenStore);
            return defaultTokenServices;
        }

        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints)
                throws Exception {
            endpoints.authorizationCodeServices(authorizationCodeServices())
                    .tokenStore(tokenStore)
                    .authenticationManager(auth)
                    .addInterceptor(handlerInterceptor)
                    .tokenServices(tokenServices)
                    .approvalStoreDisabled();
        }

链接:https ://github.com/spring-projects/spring-security-oauth/issues/1900


推荐阅读