Last week I announced the release of Spring Security 3.2 M1 that contains improved Servlet 3 support. In this post, I will introduce some of the more exciting features found in the 3.2 M1 release. Specifically, we will take a look at the following new Spring Security features:
Concurrency Support
You might ask "What is concurrency support doing in a release that has a Servlet 3 focused theme?" The reason is that the concurrency support provides a foundation for all the other features found in this release. While the concurrency support is used by the Servlet 3 integration, it can also serve as building blocks to support concurrency and Spring Security in any application. Let's take a look at Spring Security's concurrency support now.
DelegatingSecurityContextRunnable
One of the most fundamental building blocks within Spring Security's concurrency support is the DelegatingSecurityContextRunnable
. It wraps a delegate Runnable
in order to initialize the SecurityContextHolder
with a specified SecurityContext
for the delegate. It then invokes the delegate Runnable
ensuring to clear the SecurityContextHolder
afterwards. The DelegatingSecurityContextRunnable
looks something like this:
public void run() {
try {
SecurityContextHolder.setContext(securityContext);
delegate.run();
} finally {
SecurityContextHolder.clearContext();
}
}
While very simple, it makes it seamless to transfer the SecurityContext
from one Thread
to another. This is important since, in most cases, the SecurityContextHolder
acts on a per Thread
basis. For example, you might have used Spring Security's <global-method-security> support to secure one of your services. You can now easily transfer the SecurityContext
of the current Thread
to the Thread
that invokes the secured service. An example of how you might do this can be found below:
Runnable originalRunnable = new Runnable() {
public void run() {
// invoke secured service
}
};
SecurityContext context = SecurityContextHolder.getContext();
DelegatingSecurityContextRunnable wrappedRunnable =
new DelegatingSecurityContextRunnable(originalRunnable, context);
new Thread(wrappedRunnable).start();
The code above performs the following steps:
- Creates a
Runnable
that will be invoking our secured service. Notice that it is not aware of Spring Security
- Obtains the
SecurityContext
that we wish to use from the SecurityContextHolder
and initializes the DelegatingSecurityContextRunnable
- Use the
DelegatingSecurityContextRunnable
to create a Thread
- Start the
Thread
we created
Since it is quite common to create a DelegatingSecurityContextRunnable
with the SecurityContext
from the SecurityContextHolder
there is a shortcut constructor for it. The following code is the same as the code above:
Runnable originalRunnable = new Runnable() {
public void run() {
// invoke secured…