Java Oauth2弹簧引导只读连接错误

Java Oauth2弹簧引导只读连接错误,java,spring,spring-boot,spring-oauth2,Java,Spring,Spring Boot,Spring Oauth2,我不断发现下面的错误,我确实使用@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: Transient

我不断发现下面的错误,我确实使用@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)
  • 解决方案
  • 我可以通过手动将事务附加到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);
        }
    
    我还创建了SpringSecurityOAuth的问题,但它似乎不应该支持SpringBoot2.x

    任何才华横溢的人都想知道为什么事务没有在DefaultTokenServices中调用。

  • 解决方案
  • 为DefaultTokenServices创建Bean并将其传递给configurer

    @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();
            }
    
    链接:

  • 解决方案
  • 我可以通过手动将事务附加到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);
        }
    
    我还创建了SpringSecurityOAuth的问题,但它似乎不应该支持SpringBoot2.x

    任何才华横溢的人都想知道为什么事务没有在DefaultTokenServices中调用。

  • 解决方案
  • 为DefaultTokenServices创建Bean并将其传递给configurer

    @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();
            }
    

    链接:

    连接是只读的。不允许导致数据修改的查询;嵌套异常为java.sql.SQLException:连接为只读。不允许导致数据修改的查询=====>>>这意味着您无法使用修改数据库进行查询。您可能有一个带有@Transactional(readOnly=true)的方法或组件,其中的注释是DefaultTokenServices.createAccessToken中的@Transaction,这是OAuth的默认实现。您可以粘贴如何配置/设置它。我很好奇您是否有一个调用authservice的方法,如果是这样,您的方法需要@TransactionalIt是spring boot中oauth2的默认代码@SusanMustafa I在下面添加了一个解决方案,该解决方案可以工作,但仍然不知道为什么在DefaultTokenServicesConnection中不调用事务是只读的。不允许导致数据修改的查询;嵌套异常为java.sql.SQLException:连接为只读。不允许导致数据修改的查询=====>>>这意味着您无法使用修改数据库进行查询。您可能有一个带有@Transactional(readOnly=true)的方法或组件,其中的注释是DefaultTokenServices.createAccessToken中的@Transaction,这是OAuth的默认实现。您可以粘贴如何配置/设置它。我很好奇您是否有一个调用authservice的方法,如果是这样,您的方法需要@TransactionalIt是spring boot中oauth2的默认代码@SusanMustafa I在下面添加了一个解决方案,该解决方案可以工作,但仍然不知道为什么在DefaultTokenServices中不调用事务