拦截器可以在认证和动作执行之间执行吗?

Can interceptors be executed between authentication and action execution?

从容器管理的身份验证转移到 Grails 3.1.9 应用程序中的 Spring 安全插件。在容器管理的世界中,我们的 Grails 拦截器在对安全资源进行身份验证后执行。但是,对于 Spring 安全性,拦截器(具有 before() 逻辑)按以下顺序执行:

  1. 调用安全资源
  2. 拦截器栈拦截请求,returns true
  3. 重定向到表单登录页面
  4. 认证成功
  5. 重定向到请求的资源

我们有只应为经过身份验证的用户触发的拦截器。有没有办法让拦截器在第 4 步和第 5 步之间执行,而不是这个流程?或者这是我们的拦截器逻辑需要移入 Spring 安全过滤器的地方?

如果您查看 2.x 应用程序中的流程,就会更清楚一些,因为有一个 web.xml 文件,其中的几个部分 运行 的顺序更清楚,但在 2.x 和 3.x.

中基本相同

插件的过滤器链被注册为一个过滤器,并且配置为 运行 在 grailsWebRequest 过滤器之后但在 GrailsDispatcherServlet 之前。这是为了支持可能具有与默认不同的 URL 映射的注释控制器(例如 PersonController.show() 可能映射到 /person/show 但应用程序可能已将其映射到任何有效的 uri(和组合的 REST 动词),因此我需要能够搜索已编译的 URL 映射实例,以确定控制器将对当前请求执行的操作 运行。在过滤器中,我知道什么 URL 被请求,但不是要应用什么安全规则;如果一切都是基于 url 的,它将很简单并且在启动时预编译,但是使用带注释的控制器,我只知道适用于什么规则控制器方法。

Servlet 运行 在过滤器之后,这是确定和调用控制器的地方。 2.x 中的拦截器(和 Grails 过滤器(不要与 servlet 过滤器混淆))实际上是 Spring HandlerInterceptors 与 'handler' 一起组合成 HandlerExecutionChain.这是通用的,足以处理任何类型的请求,但实际上处理程序是一个控制器,因此范围比 servlet 过滤器要窄得多。

所以回到您的实际问题,您最好的选择是在添加到 Spring 安全过滤器链的过滤器中完成工作。这些实现起来非常简单,过程在 plugin docs.

中进行了描述