Spring Security reuses Filter and WebFilter APIs for security-based controller based logic within a Spring Security application. The Security Filter's should be registered with FilterChainProxy and WebFilters with WebFilterChainProxy.
However, Spring Boot's auto configuration will automatically register any Filter or WebFilter with the application. This behavior surprises users when they create a Filter or WebFilter bean to register with Spring security and it and causes problems due to ordering and duplicate invocations.
We should make it so that this works correctly out of the box for users.
Related https://github.com/spring-projects/spring-boot/issues/16500
Comment From: rwinch
One way to solve this is to introduce a new interface (e.g. SecurityFilter, ServletSecurityInterceptor,...) that replaces Spring Security's use of the servlet Filter.
The benefits of this approach are many:
- While the method signatures of
doFilterare similar between the two types, aSecurityFiltershould not be registered with the Servlet container (it is a bug to do so). A new type prevents this invalid scenario from being possible. - A standard servlet
Filtershould not necessarily (only when it is a Security relatedFilter) be registered with Spring Security. A new type prevents this invalid scenario from being possible and makes it clear where it should be registered. - A
SecurityFilterhas no need forinitordestroymethods. A new type makes it so that these methods are no longer necessary - A
SecurityFilterrequires an order. A new type can include this in the interface requirements so that it is impossible to register something without an order & ensures it is simple to find the correct order rather than having to look on other objects for it.
The configuration would add a method to register a SecurityFilter. The methods to register Filter would be deprecated for removal in Spring Security 7.0. Spring Security could consider automatically registering any SecurityFilter beans but this would make working with multiple HttpSecurity instances difficult.
To simplify using a standard Filter within Spring Security, we could add ServletSecurityFilter which implements SecurityFilter and delegates to the servlet Filter.
Spring Boot can optionally start to exclude automatic registration of a Filter that also implements SecurityFilter right away. Alternatively, Spring Boot can wait until 7.0.
A similar approach of adding a SecurityWebFilter can be taken with WebFlux.
Comment From: joshlong
Hi - I think this is super cool! Would be nice if the new filter was divorced from the servlet api.
we have Spring gRPC (paging Dr. @dsyer ), we have WebSockets, we have Spring Integration, etc., etc. not to mention reactive. I realize we'll never be able to unify reactive and non reactive, but at least let's not couple ourselves in other protocols to the HttpServletRequest type.
In the reactive world, we also have web sockets, RSocket, HTTP, etc.
It'd be nice if there was a generic filter type and then specialized implementations for various protocols and use cases.
thanks
Comment From: jzheaux
As far as ordering is concerned, it would be nice if it were abstracted away from the .class instances themselves. This will allow filters to migrate more easily to AuthenticationFilter.
For example:
public int getOrder() {
return SecurityFiltersOrder.AUTHENTICATION - 1;
}
Comment From: dsyer
The experiments I'm working on in Spring gRPC are probably very relevant. I already found it awkward to include spring-security-web. And I have copied code from a couple of places (HTTP Basic creds extraction, and SSL principal extraction) from Spring Security. The same thing will happen when I want to include OAuth2/JWT. If those could be consolidated in commonly used abstractions for preauth and HTTP basic, for instance, that would be quite likely usable across all non-web app types.