Grails-不打开特定请求路径的hibernate会话

Grails-不打开特定请求路径的hibernate会话,hibernate,spring-boot,grails,grails3,Hibernate,Spring Boot,Grails,Grails3,我们希望为Grails3应用程序实现API速率限制。为此,我们使用拦截器和redis。然而,对于每个到达Grails的请求,打开hibernate会话(打开数据库连接)是一个问题。这是一个我们不能忽视的资源消耗,因为它很容易通过简单的攻击达到MySQL连接限制 问题是,如何强制Grails不为某些URL/拦截器打开hibernate会话的最佳方法是什么。我知道像konghq.com这样的API网关对我们来说不是一个选项 我还了解负责会话管理的grailopensessioninviewinter

我们希望为Grails3应用程序实现API速率限制。为此,我们使用拦截器和redis。然而,对于每个到达Grails的请求,打开hibernate会话(打开数据库连接)是一个问题。这是一个我们不能忽视的资源消耗,因为它很容易通过简单的攻击达到MySQL连接限制

问题是,如何强制Grails不为某些URL/拦截器打开hibernate会话的最佳方法是什么。我知道像konghq.com这样的API网关对我们来说不是一个选项


我还了解负责会话管理的
grailopensessioninviewinterceptor
实现
OpenSessionInViewInterceptor
。那么,它是覆盖这个拦截器的唯一选项吗?对于那些符合速率限制的请求,您将如何打开hibernate会话?

最后,我覆盖了
GrailOpenSessionInviewinterCeptor
,只有在满足速率限制的情况下,我才打开hibernate会话

import org.grails.web.servlet.mvc.GrailsWebRequest
import org.grails.web.util.GrailsApplicationAttributes
import org.springframework.web.context.request.WebRequest

import javax.servlet.http.HttpServletRequest

class MyOpenSessionInViewInterceptor extends GrailsOpenSessionInViewInterceptor {

    @Override
    void preHandle(WebRequest request) throws DataAccessException {
        GrailsWebRequest grailsRequest = (GrailsWebRequest) request.getAttribute(GrailsApplicationAttributes.WEB_REQUEST,
                WebRequest.SCOPE_REQUEST)
        HttpServletRequest servletRequest = grailsRequest.request

        // intercept /api/* requests
        if (!servletRequest.requestURI.startsWith('/api')) {
            // if rate limits exceeded
            if (checkRateLimits) {
                servletRequest.setAttribute('MY_RATE_LIMITS_EXCEEDED', true)
                return
            }

            super.preHandle(request)
        }
    }
}
别忘了将bean注入resource.groovy

// Place your Spring DSL code here
beans = {

    // intercept opening of hibernate cache
    openSessionInViewInterceptor(MyOpenSessionInViewInterceptor) {
        hibernateDatastore = ref('hibernateDatastore')
    }
}
我把它和内部grails拦截器放在一起,在这里我检查SpringOpenSession拦截器传递的属性

class V1RateLimitInterceptor {

    V1RateLimitInterceptor() {
        match(namespace: 'api')
    }

    boolean before() {
        // request rate limits
        boolean rateLimit = (boolean) request.getAttribute('MY_RATE_LIMITS_EXCEEDED')
        if (rateLimit) {
            return false
        }

        return true
    }
}
不过,这对我们来说是一个临时解决方案,因为我们将来会使用一些API网关,如konghq.com