Polish Extract Doc Sections
This commit is contained in:
parent
ecc63f7c8c
commit
f4d032a762
|
@ -0,0 +1,33 @@
|
||||||
|
[[servlet-delegatingfilterproxy]]
|
||||||
|
= DelegatingFilterProxy
|
||||||
|
|
||||||
|
Spring provides a `Filter` implementation named `DelegatingFilterProxy` that allows bridging between the Servlet container's lifecycle and Spring's `ApplicationContext`.
|
||||||
|
The Servlet container allows registering ``Filter``s using its own standards, but it is not aware of Spring defined Beans.
|
||||||
|
`DelegatingFilterProxy` can be registered via standard Servlet container mechanisms, but delegate all the work to a Spring Bean that implements `Filter`.
|
||||||
|
|
||||||
|
Here is a picture of how `DelegatingFilterProxy` fits into the <<servlet-filterchain-figure>>.
|
||||||
|
|
||||||
|
.DelegatingFilterProxy
|
||||||
|
[[servlet-delegatingfilterproxy-figure]]
|
||||||
|
image::{figures}/delegatingfilterproxy.png[]
|
||||||
|
|
||||||
|
`DelegatingFilterProxy` looks up __Bean Filter~0~__ from the `ApplicationContext` and then invokes __Bean Filter~0~__.
|
||||||
|
The pseudo code of `DelegatingFilterProxy` can be seen below.
|
||||||
|
|
||||||
|
.`DelegatingFilterProxy` Pseudo Code
|
||||||
|
====
|
||||||
|
[source,java,subs="+quotes,+macros"]
|
||||||
|
----
|
||||||
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
|
||||||
|
// Lazily get Filter that was registered as a Spring Bean
|
||||||
|
// For the example in <<servlet-delegatingfilterproxy-figure>> `delegate` is an instance of __Bean Filter~0~__
|
||||||
|
Filter delegate = getFilterBean(someBeanName);
|
||||||
|
// delegate work to the Spring Bean
|
||||||
|
delegate.doFilter(request, response);
|
||||||
|
}
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
Another benefit of `DelegatingFilterProxy` is that it allows delaying looking `Filter` bean instances.
|
||||||
|
This is important because the container needs to register the `Filter` instances before the container can startup.
|
||||||
|
However, Spring typically uses a `ContextLoaderListener` to load the Spring Beans which will not be done until after the `Filter` instances need to be registered.
|
|
@ -0,0 +1,10 @@
|
||||||
|
[[servlet-filterchainproxy]]
|
||||||
|
= FilterChainProxy
|
||||||
|
|
||||||
|
Spring Security's Servlet support is contained within `FilterChainProxy`.
|
||||||
|
`FilterChainProxy` is a special `Filter` provided by Spring Security that allows delegating to many `Filter` instances through <<servlet-securityfilterchain,`SecurityFilterChain`>>.
|
||||||
|
Since `FilterChainProxy` is a Bean, it is typically wrapped in a <<servlet-delegatingfilterproxy>>.
|
||||||
|
|
||||||
|
.FilterChainProxy
|
||||||
|
[[servlet-filterchainproxy-figure]]
|
||||||
|
image::{figures}/filterchainproxy.png[]
|
|
@ -0,0 +1,33 @@
|
||||||
|
[[servlet-filters-review]]
|
||||||
|
= A Review of ``Filter``s
|
||||||
|
|
||||||
|
Spring Security's Servlet support is based on Servlet ``Filter``s, so it is helpful to look at the role of ``Filter``s generally first.
|
||||||
|
The picture below shows the typical layering of the handlers for a single HTTP request.
|
||||||
|
|
||||||
|
.FilterChain
|
||||||
|
[[servlet-filterchain-figure]]
|
||||||
|
image::{figures}/filterchain.png[]
|
||||||
|
|
||||||
|
The client sends a request to the application, and the container creates a `FilterChain` which contains the ``Filter``s and `Servlet` that should process the `HttpServletRequest` based on the path of the request URI.
|
||||||
|
At most one `Servlet` can handle a single `HttpServletRequest` and `HttpServletResponse`.
|
||||||
|
However, more than one `Filter` can be used to:
|
||||||
|
|
||||||
|
* Prevent downstream ``Filter``s or the `Servlet` from being invoked.
|
||||||
|
In this instance the `Filter` will typically write the `HttpServletResponse`.
|
||||||
|
* Modify the `HttpServletRequest` or `HttpServletResponse` used by the downstream ``Filter``s and `Servlet`
|
||||||
|
|
||||||
|
The power of the `Filter` comes from the `FilterChain` that is passed into it.
|
||||||
|
|
||||||
|
.`FilterChain` Usage Example
|
||||||
|
===
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
|
||||||
|
// do something before the rest of the application
|
||||||
|
chain.doFilter(request, response); // invoke the rest of the application
|
||||||
|
// do something after the rest of the application
|
||||||
|
}
|
||||||
|
----
|
||||||
|
===
|
||||||
|
|
||||||
|
Since a `Filter` only impacts downstream ``Filter``s and the `Servlet`, the order each `Filter` is invoked is extremely important.
|
|
@ -7,168 +7,15 @@ This section discusses Spring Security's high level architecture within Servlet
|
||||||
We build on this high level understanding within each section of the reference.
|
We build on this high level understanding within each section of the reference.
|
||||||
// FIXME: Add links to other sections of architecture
|
// FIXME: Add links to other sections of architecture
|
||||||
|
|
||||||
[[servlet-filters-review]]
|
include::filters.adoc[leveloffset=+1]
|
||||||
== A Review of ``Filter``s
|
|
||||||
|
|
||||||
Spring Security's Servlet support is based on Servlet ``Filter``s, so it is helpful to look at the role of ``Filter``s generally first.
|
include::delegating-filter-proxy.adoc[leveloffset=+1]
|
||||||
The picture below shows the typical layering of the handlers for a single HTTP request.
|
|
||||||
|
|
||||||
.FilterChain
|
include::filter-chain-proxy.adoc[leveloffset=+1]
|
||||||
[[servlet-filterchain-figure]]
|
|
||||||
image::{figures}/filterchain.png[]
|
|
||||||
|
|
||||||
The client sends a request to the application, and the container creates a `FilterChain` which contains the ``Filter``s and `Servlet` that should process the `HttpServletRequest` based on the path of the request URI.
|
include::security-filter-chain.adoc[leveloffset=+1]
|
||||||
At most one `Servlet` can handle a single `HttpServletRequest` and `HttpServletResponse`.
|
|
||||||
However, more than one `Filter` can be used to:
|
|
||||||
|
|
||||||
* Prevent downstream ``Filter``s or the `Servlet` from being invoked.
|
include::security-filters.adoc[leveloffset=+1]
|
||||||
In this instance the `Filter` will typically write the `HttpServletResponse`.
|
|
||||||
* Modify the `HttpServletRequest` or `HttpServletResponse` used by the downstream ``Filter``s and `Servlet`
|
|
||||||
|
|
||||||
The power of the `Filter` comes from the `FilterChain` that is passed into it.
|
|
||||||
|
|
||||||
.`FilterChain` Usage Example
|
|
||||||
====
|
|
||||||
[source,java]
|
|
||||||
----
|
|
||||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
|
|
||||||
// do something before the rest of the application
|
|
||||||
chain.doFilter(request, response); // invoke the rest of the application
|
|
||||||
// do something after the rest of the application
|
|
||||||
}
|
|
||||||
----
|
|
||||||
====
|
|
||||||
|
|
||||||
Since a `Filter` only impacts downstream ``Filter``s and the `Servlet`, the order each `Filter` is invoked is extremely important.
|
|
||||||
|
|
||||||
[[servlet-delegatingfilterproxy]]
|
|
||||||
== DelegatingFilterProxy
|
|
||||||
|
|
||||||
Spring provides a `Filter` implementation named `DelegatingFilterProxy` that allows bridging between the Servlet container's lifecycle and Spring's `ApplicationContext`.
|
|
||||||
The Servlet container allows registering ``Filter``s using its own standards, but it is not aware of Spring defined Beans.
|
|
||||||
`DelegatingFilterProxy` can be registered via standard Servlet container mechanisms, but delegate all the work to a Spring Bean that implements `Filter`.
|
|
||||||
|
|
||||||
Here is a picture of how `DelegatingFilterProxy` fits into the <<servlet-filterchain-figure>>.
|
|
||||||
|
|
||||||
.DelegatingFilterProxy
|
|
||||||
[[servlet-delegatingfilterproxy-figure]]
|
|
||||||
image::{figures}/delegatingfilterproxy.png[]
|
|
||||||
|
|
||||||
`DelegatingFilterProxy` looks up __Bean Filter~0~__ from the `ApplicationContext` and then invokes __Bean Filter~0~__.
|
|
||||||
The pseudo code of `DelegatingFilterProxy` can be seen below.
|
|
||||||
|
|
||||||
.`DelegatingFilterProxy` Pseudo Code
|
|
||||||
====
|
|
||||||
[source,java,subs="+quotes,+macros"]
|
|
||||||
----
|
|
||||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
|
|
||||||
// Lazily get Filter that was registered as a Spring Bean
|
|
||||||
// For the example in <<servlet-delegatingfilterproxy-figure>> `delegate` is an instance of __Bean Filter~0~__
|
|
||||||
Filter delegate = getFilterBean(someBeanName);
|
|
||||||
// delegate work to the Spring Bean
|
|
||||||
delegate.doFilter(request, response);
|
|
||||||
}
|
|
||||||
----
|
|
||||||
====
|
|
||||||
|
|
||||||
Another benefit of `DelegatingFilterProxy` is that it allows delaying looking `Filter` bean instances.
|
|
||||||
This is important because the container needs to register the `Filter` instances before the container can startup.
|
|
||||||
However, Spring typically uses a `ContextLoaderListener` to load the Spring Beans which will not be done until after the `Filter` instances need to be registered.
|
|
||||||
|
|
||||||
[[servlet-filterchainproxy]]
|
|
||||||
== FilterChainProxy
|
|
||||||
|
|
||||||
Spring Security's Servlet support is contained within `FilterChainProxy`.
|
|
||||||
`FilterChainProxy` is a special `Filter` provided by Spring Security that allows delegating to many `Filter` instances through <<servlet-securityfilterchain,`SecurityFilterChain`>>.
|
|
||||||
Since `FilterChainProxy` is a Bean, it is typically wrapped in a <<servlet-delegatingfilterproxy>>.
|
|
||||||
|
|
||||||
.FilterChainProxy
|
|
||||||
[[servlet-filterchainproxy-figure]]
|
|
||||||
image::{figures}/filterchainproxy.png[]
|
|
||||||
|
|
||||||
[[servlet-securityfilterchain]]
|
|
||||||
== SecurityFilterChain
|
|
||||||
|
|
||||||
{security-api-url}org/springframework/security/web/SecurityFilterChain.html[`SecurityFilterChain`] is used by <<servlet-filterchainproxy>> to determine which Spring Security ``Filter``s should be invoked for this request.
|
|
||||||
|
|
||||||
The <<servlet-security-filters,Security Filters>> in `SecurityFilterChain` are typically Beans, but they are registered with `FilterChainProxy` instead of <<servlet-delegatingfilterproxy>>.
|
|
||||||
`FilterChainProxy` provides a number of advantages to registering directly with the Servlet container or <<servlet-delegatingfilterproxy>>.
|
|
||||||
First, it provides a starting point for all of Spring Security's Servlet support.
|
|
||||||
For that reason, if you are attempting to troubleshoot Spring Security's Servlet support, adding a debug point in `FilterChainProxy` is a great place to start.
|
|
||||||
|
|
||||||
Second, since `FilterChainProxy` is central to Spring Security usage it can perform tasks that are not viewed as optional.
|
|
||||||
// FIXME: Add a link to SecurityContext
|
|
||||||
For example, it clears out the `SecurityContext` to avoid memory leaks.
|
|
||||||
It also applies Spring Security's <<servlet-httpfirewall,`HttpFirewall`>> to protect applications against certain types of attacks.
|
|
||||||
|
|
||||||
In addition, it provides more flexibility in determining when a `SecurityFilterChain` should be invoked.
|
|
||||||
In a Servlet container, ``Filter``s are invoked based upon the URL alone.
|
|
||||||
// FIXME: Link to RequestMatcher
|
|
||||||
However, `FilterChainProxy` can determine invocation based upon anything in the `HttpServletRequest` by leveraging the `RequestMatcher` interface.
|
|
||||||
|
|
||||||
In fact, `FilterChainProxy` can be used to determine which `SecurityFilterChain` should be used.
|
|
||||||
This allows providing a totally separate configuration for different _slices_ if your application.
|
|
||||||
|
|
||||||
.Multiple SecurityFilterChain
|
|
||||||
[[servlet-multi-securityfilterchain-figure]]
|
|
||||||
image::{figures}/multi-securityfilterchain.png[]
|
|
||||||
|
|
||||||
In the <<servlet-multi-securityfilterchain-figure>> Figure `FilterChainProxy` decides which `SecurityFilterChain` should be used.
|
|
||||||
Only the first `SecurityFilterChain` that matches will be invoked.
|
|
||||||
If a URL of `/api/messages/` is requested, it will first match on ``SecurityFilterChain~0~``'s pattern of `+/api/**+`, so only `SecurityFilterChain~0~` will be invoked even though it also matches on ``SecurityFilterChain~n~``.
|
|
||||||
If a URL of `/messages/` is requested, it will not match on ``SecurityFilterChain~0~``'s pattern of `+/api/**+`, so `FilterChainProxy` will continue trying each `SecurityFilterChain`.
|
|
||||||
Assuming that no other, `SecurityFilterChain` instances match `SecurityFilterChain~n~` will be invoked.
|
|
||||||
// FIXME add link to pattern matching
|
|
||||||
|
|
||||||
Notice that `SecurityFilterChain~0~` has only three security ``Filter``s instances configured.
|
|
||||||
However, `SecurityFilterChain~n~` has four security ``Filter``s configured.
|
|
||||||
It is important to note that each `SecurityFilterChain` can be unique and configured in isolation.
|
|
||||||
In fact, a `SecurityFilterChain` might have zero security ``Filter``s if the application wants Spring Security to ignore certain requests.
|
|
||||||
// FIXME: add link to configuring multiple `SecurityFilterChain` instances
|
|
||||||
|
|
||||||
[[servlet-security-filters]]
|
|
||||||
== Security Filters
|
|
||||||
|
|
||||||
The Security Filters are inserted into the <<servlet-filterchainproxy>> with the <<servlet-securityfilterchain>> API.
|
|
||||||
The <<servlet-filters-review,order of ``Filter``>>s matters.
|
|
||||||
It is typically not necessary to know the ordering of Spring Security's ``Filter``s.
|
|
||||||
However, there are times that it is beneficial to know the ordering
|
|
||||||
|
|
||||||
Below is a comprehensive list of Spring Security Filter ordering:
|
|
||||||
|
|
||||||
* ChannelProcessingFilter
|
|
||||||
* ConcurrentSessionFilter
|
|
||||||
* WebAsyncManagerIntegrationFilter
|
|
||||||
* SecurityContextPersistenceFilter
|
|
||||||
* HeaderWriterFilter
|
|
||||||
* CorsFilter
|
|
||||||
* CsrfFilter
|
|
||||||
* LogoutFilter
|
|
||||||
* OAuth2AuthorizationRequestRedirectFilter
|
|
||||||
* Saml2WebSsoAuthenticationRequestFilter
|
|
||||||
* X509AuthenticationFilter
|
|
||||||
* AbstractPreAuthenticatedProcessingFilter
|
|
||||||
* CasAuthenticationFilter
|
|
||||||
* OAuth2LoginAuthenticationFilter
|
|
||||||
* Saml2WebSsoAuthenticationFilter
|
|
||||||
* UsernamePasswordAuthenticationFilter
|
|
||||||
* ConcurrentSessionFilter
|
|
||||||
* OpenIDAuthenticationFilter
|
|
||||||
* DefaultLoginPageGeneratingFilter
|
|
||||||
* DefaultLogoutPageGeneratingFilter
|
|
||||||
* DigestAuthenticationFilter
|
|
||||||
* BearerTokenAuthenticationFilter
|
|
||||||
* BasicAuthenticationFilter
|
|
||||||
* RequestCacheAwareFilter
|
|
||||||
* SecurityContextHolderAwareRequestFilter
|
|
||||||
* JaasApiIntegrationFilter
|
|
||||||
* RememberMeAuthenticationFilter
|
|
||||||
* AnonymousAuthenticationFilter
|
|
||||||
* OAuth2AuthorizationCodeGrantFilter
|
|
||||||
* SessionManagementFilter
|
|
||||||
* <<servlet-exceptiontranslationfilter,`ExceptionTranslationFilter`>>
|
|
||||||
* <<servlet-authorization-filtersecurityinterceptor,`FilterSecurityInterceptor`>>
|
|
||||||
* SwitchUserFilter
|
|
||||||
|
|
||||||
include::exception-translation-filter.adoc[leveloffset=+1]
|
include::exception-translation-filter.adoc[leveloffset=+1]
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
[[servlet-securityfilterchain]]
|
||||||
|
= SecurityFilterChain
|
||||||
|
|
||||||
|
{security-api-url}org/springframework/security/web/SecurityFilterChain.html[`SecurityFilterChain`] is used by <<servlet-filterchainproxy>> to determine which Spring Security ``Filter``s should be invoked for this request.
|
||||||
|
|
||||||
|
The <<servlet-security-filters,Security Filters>> in `SecurityFilterChain` are typically Beans, but they are registered with `FilterChainProxy` instead of <<servlet-delegatingfilterproxy>>.
|
||||||
|
`FilterChainProxy` provides a number of advantages to registering directly with the Servlet container or <<servlet-delegatingfilterproxy>>.
|
||||||
|
First, it provides a starting point for all of Spring Security's Servlet support.
|
||||||
|
For that reason, if you are attempting to troubleshoot Spring Security's Servlet support, adding a debug point in `FilterChainProxy` is a great place to start.
|
||||||
|
|
||||||
|
Second, since `FilterChainProxy` is central to Spring Security usage it can perform tasks that are not viewed as optional.
|
||||||
|
// FIXME: Add a link to SecurityContext
|
||||||
|
For example, it clears out the `SecurityContext` to avoid memory leaks.
|
||||||
|
It also applies Spring Security's <<servlet-httpfirewall,`HttpFirewall`>> to protect applications against certain types of attacks.
|
||||||
|
|
||||||
|
In addition, it provides more flexibility in determining when a `SecurityFilterChain` should be invoked.
|
||||||
|
In a Servlet container, ``Filter``s are invoked based upon the URL alone.
|
||||||
|
// FIXME: Link to RequestMatcher
|
||||||
|
However, `FilterChainProxy` can determine invocation based upon anything in the `HttpServletRequest` by leveraging the `RequestMatcher` interface.
|
||||||
|
|
||||||
|
In fact, `FilterChainProxy` can be used to determine which `SecurityFilterChain` should be used.
|
||||||
|
This allows providing a totally separate configuration for different _slices_ if your application.
|
||||||
|
|
||||||
|
.Multiple SecurityFilterChain
|
||||||
|
[[servlet-multi-securityfilterchain-figure]]
|
||||||
|
image::{figures}/multi-securityfilterchain.png[]
|
||||||
|
|
||||||
|
In the <<servlet-multi-securityfilterchain-figure>> Figure `FilterChainProxy` decides which `SecurityFilterChain` should be used.
|
||||||
|
Only the first `SecurityFilterChain` that matches will be invoked.
|
||||||
|
If a URL of `/api/messages/` is requested, it will first match on ``SecurityFilterChain~0~``'s pattern of `+/api/**+`, so only `SecurityFilterChain~0~` will be invoked even though it also matches on ``SecurityFilterChain~n~``.
|
||||||
|
If a URL of `/messages/` is requested, it will not match on ``SecurityFilterChain~0~``'s pattern of `+/api/**+`, so `FilterChainProxy` will continue trying each `SecurityFilterChain`.
|
||||||
|
Assuming that no other, `SecurityFilterChain` instances match `SecurityFilterChain~n~` will be invoked.
|
||||||
|
// FIXME add link to pattern matching
|
||||||
|
|
||||||
|
Notice that `SecurityFilterChain~0~` has only three security ``Filter``s instances configured.
|
||||||
|
However, `SecurityFilterChain~n~` has four security ``Filter``s configured.
|
||||||
|
It is important to note that each `SecurityFilterChain` can be unique and configured in isolation.
|
||||||
|
In fact, a `SecurityFilterChain` might have zero security ``Filter``s if the application wants Spring Security to ignore certain requests.
|
||||||
|
// FIXME: add link to configuring multiple `SecurityFilterChain` instances
|
|
@ -0,0 +1,43 @@
|
||||||
|
[[servlet-security-filters]]
|
||||||
|
= Security Filters
|
||||||
|
|
||||||
|
The Security Filters are inserted into the <<servlet-filterchainproxy>> with the <<servlet-securityfilterchain>> API.
|
||||||
|
The <<servlet-filters-review,order of ``Filter``>>s matters.
|
||||||
|
It is typically not necessary to know the ordering of Spring Security's ``Filter``s.
|
||||||
|
However, there are times that it is beneficial to know the ordering
|
||||||
|
|
||||||
|
Below is a comprehensive list of Spring Security Filter ordering:
|
||||||
|
|
||||||
|
* ChannelProcessingFilter
|
||||||
|
* ConcurrentSessionFilter
|
||||||
|
* WebAsyncManagerIntegrationFilter
|
||||||
|
* SecurityContextPersistenceFilter
|
||||||
|
* HeaderWriterFilter
|
||||||
|
* CorsFilter
|
||||||
|
* CsrfFilter
|
||||||
|
* LogoutFilter
|
||||||
|
* OAuth2AuthorizationRequestRedirectFilter
|
||||||
|
* Saml2WebSsoAuthenticationRequestFilter
|
||||||
|
* X509AuthenticationFilter
|
||||||
|
* AbstractPreAuthenticatedProcessingFilter
|
||||||
|
* CasAuthenticationFilter
|
||||||
|
* OAuth2LoginAuthenticationFilter
|
||||||
|
* Saml2WebSsoAuthenticationFilter
|
||||||
|
* UsernamePasswordAuthenticationFilter
|
||||||
|
* ConcurrentSessionFilter
|
||||||
|
* OpenIDAuthenticationFilter
|
||||||
|
* DefaultLoginPageGeneratingFilter
|
||||||
|
* DefaultLogoutPageGeneratingFilter
|
||||||
|
* DigestAuthenticationFilter
|
||||||
|
* BearerTokenAuthenticationFilter
|
||||||
|
* BasicAuthenticationFilter
|
||||||
|
* RequestCacheAwareFilter
|
||||||
|
* SecurityContextHolderAwareRequestFilter
|
||||||
|
* JaasApiIntegrationFilter
|
||||||
|
* RememberMeAuthenticationFilter
|
||||||
|
* AnonymousAuthenticationFilter
|
||||||
|
* OAuth2AuthorizationCodeGrantFilter
|
||||||
|
* SessionManagementFilter
|
||||||
|
* <<servlet-exceptiontranslationfilter,`ExceptionTranslationFilter`>>
|
||||||
|
* <<servlet-authorization-filtersecurityinterceptor,`FilterSecurityInterceptor`>>
|
||||||
|
* SwitchUserFilter
|
Loading…
Reference in New Issue