Previously SecurityContextCallableProcessingInterceptor used afterCompletion
to clear the SecurityContextHolder. This does not work since afterCompletion
is invoked on the Servlet Container thread.
Now SecurityContextCallableProcessingInterceptor clears the
SecurityContextHolder on postProcess which is invoked on the same thread
that the Callable is processed on.
Previously, if the Principal returned by getPreAuthenticatedPrincipal was not a String,
it prevented requiresAuthentication from detecting when the Principal was the same.
This caused the need to authenticate the user for every request even when the Principal
did not change.
Now requiresAuthentication will check to see if the result of
getPreAuthenticatedPrincipal is equal to the current Authentication.getPrincipal().
Previously a NullPointerException would occur if an HttpServletRequest.getMethod()
returned null.
Now AntPathRequestMatcher and RegexpRequestMatcher will handle if the
HttpServletRequest.getMethod() returns null. While under normal circumstances,
it is unlikely for the method to be null this can occur when using
DefaultWebInvocationPrivilegeEvaluator.isAllowed(String, Authentication).
Previously SaveContextOnUpdateOrErrorResponseWrapper would save the SecurityContext on a different
Threads than the one it was created on. This causes issues with Async Web requests which may write
to the response on a new Thread.
Now SaveContextOnUpdateOrErrorResponseWrapper will not save the SecurityContext when a different
Thread invokes any of the methods that commit the response. This prevents issues with Async
processing. However, explicit calls to SecurityContextRepository.save will still save the
SecurityContext since it invokes the saveRequest method rather than private doSave method within
the SaveContextOnUpdateOrErrorResponseWrapper which contains the logic to prevent saving from
another Thread.
Previously there was a race condition could occur when the user attempts to access
a slow resource and then logs out which would result in the user not being logged
out.
SecurityContextLogoutHandler will now remove the Authentication from the
SecurityContext to protect against this scenario.
Previously Spring Security did not save the Security Context immediately prior
to the following methods being invoked:
- HttpServletResonse.flushBuffer()
- HttpServletResonse.getWriter().close()
- HttpServletResonse.getWriter().flush()
- HttpServletRespose.getOutputStream().close()
- HttpServletRespose.getOutputStream().flush()
This meant that the client could get a response prior to the SecurityContext
being stored. After the client got the response, it would make another request
and this would not yet be authenticated. The reason this can occur is because
all of the above methods commit the response, which means that the server can
signal to the client the response is completed. A similar issue happened in
SEC-398.
Now the previously listed methods are wrapped in order to ensure the SecurityContext
is persisted prior to the response being committed.
When SEC-1950 was introduced it caused problems when a <filter-mapping> was mapped
to multiple dispatchers (i.e. REQUEST and FORWARD) since when the second dispatcher
completed execution it cleared the SecurityContext and the original FilterChain
would then save the cleared out SecurityContext.
We now use a pattern similar to the OncePerRequestFilter to only invoke
SecurityContextHolder.clearContext() on the first invocation of the Filter. We do not simply extend
OncePerRequestFilter because we want to invoke the delegate filters for every request.
Previously communication errors with LDAP were only logged at debug level.
Communication errors (along with other non-authenticated related NamingExceptions)
are now logged as error messages. We created an InternalAuthetnicationServiceException
to represent errors that should be logged as errors to distinguish between internal
and external authentication failures. For example, we do not want an OpenID Provider
being able to report errors that cause our logs to fill up. However, an LDAP system is
internal and should be trusted so logging at an error level makes sense.
Previously subclasses of AbstractSecurityInterceptor did not restore the original
Authentication when RunAsManager was used and an Exception was thrown in the
original method.
AbstractSecurityInterceptor has added a new method finallyInvocation which
should be invoked in a finally block immediately after the original invocation
which will restore the original Authentication. All existing sub classes have
been updated to use this new method.
Previously JdbcTokenRepositoryImpl would log an error with a misleading
message when the token series was missing.
Now JdbcTokenRepositoryImpl logs missing token series at info level with
a more informative message.
This fixes two issues introduced by SEC-1229
* SessionRegistry.registerNewSession is invoked twice
* SessionRegistry.removeSession is invoked twice (once by the
ConcurrentSessionControlStrategy#onSessionChange and once by
SessionRegistryImpl#onApplicationEvent). This is not nearly
as problematic since the interface states that implementations
should be handle removing the session twice. However, as removing
twice requires an unnecessary database hit we should only remove
sessions once.