parent
32ee30e8a1
commit
6b0891b081
|
@ -3,34 +3,8 @@
|
|||
There are some key filters which will always be used in a web application which uses Spring Security, so we'll look at these and their supporting classes and interfaces first.
|
||||
We won't cover every feature, so be sure to look at the Javadoc for them if you want to get the complete picture.
|
||||
|
||||
[[exception-translation-filter]]
|
||||
=== ExceptionTranslationFilter
|
||||
The `ExceptionTranslationFilter` sits above the `FilterSecurityInterceptor` in the security filter stack.
|
||||
It doesn't do any actual security enforcement itself, but handles exceptions thrown by the security interceptors and provides suitable and HTTP responses.
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
|
||||
<bean id="exceptionTranslationFilter"
|
||||
class="org.springframework.security.web.access.ExceptionTranslationFilter">
|
||||
<property name="authenticationEntryPoint" ref="authenticationEntryPoint"/>
|
||||
<property name="accessDeniedHandler" ref="accessDeniedHandler"/>
|
||||
</bean>
|
||||
|
||||
<bean id="authenticationEntryPoint"
|
||||
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
|
||||
<property name="loginFormUrl" value="/login.jsp"/>
|
||||
</bean>
|
||||
|
||||
<bean id="accessDeniedHandler"
|
||||
class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
|
||||
<property name="errorPage" value="/accessDenied.htm"/>
|
||||
</bean>
|
||||
|
||||
----
|
||||
|
||||
[[auth-entry-point]]
|
||||
==== AuthenticationEntryPoint
|
||||
=== AuthenticationEntryPoint
|
||||
The `AuthenticationEntryPoint` will be called if the user requests a secure HTTP resource but they are not authenticated.
|
||||
An appropriate `AuthenticationException` or `AccessDeniedException` will be thrown by a security interceptor further down the call stack, triggering the `commence` method on the entry point.
|
||||
This does the job of presenting the appropriate response to the user so that authentication can begin.
|
||||
|
@ -39,7 +13,7 @@ The actual implementation used will depend on the authentication mechanism you w
|
|||
|
||||
|
||||
[[access-denied-handler]]
|
||||
==== AccessDeniedHandler
|
||||
=== AccessDeniedHandler
|
||||
What happens if a user is already authenticated and they try to access a protected resource? In normal usage, this shouldn't happen because the application workflow should be restricted to operations to which a user has access.
|
||||
For example, an HTML link to an administration page might be hidden from users who do not have an admin role.
|
||||
You can't rely on hiding links for security though, as there's always a possibility that a user will just enter the URL directly in an attempt to bypass the restrictions.
|
||||
|
@ -62,7 +36,7 @@ See <<nsa-access-denied-handler,the namespace appendix>> for more details.
|
|||
|
||||
|
||||
[[request-caching]]
|
||||
==== SavedRequest s and the RequestCache Interface
|
||||
=== SavedRequest s and the RequestCache Interface
|
||||
Another responsibility of `ExceptionTranslationFilter` responsibilities is to save the current request before invoking the `AuthenticationEntryPoint`.
|
||||
This allows the request to be restored after the user has authenticated (see previous overview of <<tech-intro-web-authentication,web authentication>>).
|
||||
A typical example would be where the user logs in with a form, and is then redirected to the original URL by the default `SavedRequestAwareAuthenticationSuccessHandler` (see <<form-login-flow-handling,below>>).
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
[[servlet-exceptiontranslationfilter]]
|
||||
= Handling Security Exceptions
|
||||
:figures: images/servlet/architecture
|
||||
:icondir: images/icons
|
||||
|
||||
|
||||
The {security-api-url}org/springframework/security/web/access/ExceptionTranslationFilter.html[`ExceptionTranslationFilter`] allows translation of {security-api-url}org/springframework/security/access/AccessDeniedException.html[`AccessDeniedException`] and {security-api-url}/org/springframework/security/core/AuthenticationException.html[`AuthenticationException`] into HTTP responses.
|
||||
|
||||
`ExceptionTranslationFilter` is inserted into the <<servlet-filterchainproxy>> as one of the <<servlet-security-filters>>.
|
||||
|
||||
image::{figures}/exceptiontranslationfilter.png[]
|
||||
|
||||
|
||||
* image:{icondir}/number_1.png[] First, the `ExceptionTranslationFilter` invokes `FilterChain.doFilter(request, response)` to invoke the rest of the application.
|
||||
* image:{icondir}/number_2.png[] If the user is not authenticated or it is an `AuthenticationException`, then __Start Authentication__.
|
||||
** The <<servlet-authentication-securitycontextholder>> is cleared out
|
||||
** The `HttpServletRequest` is saved in the {security-api-url}org/springframework/security/web/savedrequest/RequestCache.html[`RequestCache`].
|
||||
When the user successfully authenticates, the `RequestCache` is used to replay the original request.
|
||||
// FIXME: add link to authentication success
|
||||
** The `AuthenticationEntryPoint` is used to request credentials from the client.
|
||||
For example, it might redirect to a log in page or send a `WWW-Authenticate` header.
|
||||
// FIXME: link to AuthenticationEntryPoint
|
||||
* image:{icondir}/number_3.png[] Otherwise if it is an `AccessDeniedException`, then __Access Denied__.
|
||||
The `AccessDeniedHandler` is invoked to handle access denied.
|
||||
// FIXME: link to AccessDeniedHandler
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
If the application does not throw an `AccessDeniedException` or an `AuthenticationException`, then `ExceptionTranslationFilter` does not do anything.
|
||||
====
|
||||
|
||||
The pseudocode for `ExceptionTranslationFilter` looks something like this:
|
||||
|
||||
.ExceptionTranslationFilter pseudocode
|
||||
[source,java]
|
||||
----
|
||||
try {
|
||||
filterChain.doFilter(request, response); // <1>
|
||||
} catch (AccessDeniedException | AuthenticationException e) {
|
||||
if (!authenticated || e instanceof AuthenticationException) {
|
||||
startAuthentication(); // <2>
|
||||
} else {
|
||||
accessDenied(); // <3>
|
||||
}
|
||||
}
|
||||
----
|
||||
<1> You will recall from <<servlet-filters-review>> that invoking `FilterChain.doFilter(request, response)` is the equivalent of invoking the rest of the application.
|
||||
This means that if another part of the application, (i.e. <<servlet-authorization-filtersecurityinterceptor,`FilterSecurityInterceptor`>> or method security) throws an `AuthenticationException` or `AccessDeniedException` it will be caught and handled here.
|
||||
<2> If the user is not authenticated or it is an `AuthenticationException`, then __Start Authentication__.
|
||||
<3> Otherwise, __Access Denied__
|
|
@ -161,10 +161,12 @@ Below is a comprehensive list of Spring Security Filter ordering:
|
|||
* AnonymousAuthenticationFilter
|
||||
* OAuth2AuthorizationCodeGrantFilter
|
||||
* SessionManagementFilter
|
||||
* ExceptionTranslationFilter
|
||||
* <<servlet-exceptiontranslationfilter,`ExceptionTranslationFilter`>>
|
||||
* <<servlet-authorization-filtersecurityinterceptor,`FilterSecurityInterceptor`>>
|
||||
* SwitchUserFilter
|
||||
|
||||
include::exception-translation-filter.adoc[leveloffset=+1]
|
||||
|
||||
include::technical-overview.adoc[]
|
||||
|
||||
include::core-filters.adoc[]
|
||||
|
|
|
@ -276,14 +276,6 @@ Otherwise, you'll receive back an HTTP error code 403, which means "forbidden".
|
|||
Spring Security has distinct classes responsible for most of the steps described above.
|
||||
The main participants (in the order that they are used) are the `ExceptionTranslationFilter`, an `AuthenticationEntryPoint` and an "authentication mechanism", which is responsible for calling the `AuthenticationManager` which we saw in the previous section.
|
||||
|
||||
|
||||
==== ExceptionTranslationFilter
|
||||
`ExceptionTranslationFilter` is a Spring Security filter that has responsibility for detecting any Spring Security exceptions that are thrown.
|
||||
Such exceptions will generally be thrown by an `AbstractSecurityInterceptor`, which is the main provider of authorization services.
|
||||
We will discuss `AbstractSecurityInterceptor` in the next section, but for now we just need to know that it produces Java exceptions and knows nothing about HTTP or how to go about authenticating a principal.
|
||||
Instead the `ExceptionTranslationFilter` offers this service, with specific responsibility for either returning error code 403 (if the principal has been authenticated and therefore simply lacks sufficient access - as per step seven above), or launching an `AuthenticationEntryPoint` (if the principal has not been authenticated and therefore we need to go commence step three).
|
||||
|
||||
|
||||
[[tech-intro-auth-entry-point]]
|
||||
==== AuthenticationEntryPoint
|
||||
The `AuthenticationEntryPoint` is responsible for step three in the above list.
|
||||
|
|
Loading…
Reference in New Issue