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…