mwersch
mwersch

Reputation: 115

Can interceptors be executed between authentication and action execution?

Moving from container-managed authentication to the Spring Security plugin in a Grails 3.1.9 app. In the container-managed world, our Grails interceptors executed AFTER authentication for a secured resource. However, with Spring Security, the interceptors (with before() logic) execute with the following sequence:

  1. Call to a secured resource
  2. Interceptor stack intercepts the request, returns true
  3. Redirected to form login page
  4. Successful authentication
  5. Redirection to the requested resource

We have interceptors that should only fire for authenticated users. Is there a way to have interceptors executed between step 4 & 5 instead of this flow? Or is this where our interceptor logic needs to move into Spring Security filters?

Upvotes: 4

Views: 723

Answers (1)

Burt Beckwith
Burt Beckwith

Reputation: 75671

It's a little more clear if you look at the flow in a 2.x app since there's a web.xml file where it's more clear what order several of the parts run in, but it's basically the same in 2.x and 3.x.

The plugin's filter chain is registered as one filter and it's configured to run after the grailsWebRequest filter but before the GrailsDispatcherServlet. This is to support annotated controllers that may have URL mappings that are different from the default (e.g. PersonController.show() may map to /person/show but the app could have mapped it to any valid uri (and combination of REST verb(s)), so I need to be able to search the compiled URL mapping instances to figure out what controller action will run for the current request. In the filter, I know what URL is being requested, but not what security rule(s) to apply; if everything was url-based it would be simple and precompiled at startup, but with annotated controllers, I only know what rules apply to controller methods.

The servlet runs after the filters, and that's where the controller is determined and invoked. Interceptors (and Grails filters (not to be confused with servlet Filters) in 2.x) are actually Spring HandlerInterceptors that get composed along with a 'handler' into a HandlerExecutionChain. This is generic enough to work with any type of request but in practice the handler is a controller, so the scope is much narrower than if it were a servlet Filter.

So to get back to your actual question, your best option is to do the work in a filter that's added to the Spring Security filter chain. These are pretty simple to implement and the process is described in the plugin docs.

Upvotes: 3

Related Questions