As a preamble to the SpringOne Platform Conference, the folks at Pivotal have released Spring Security 5.0.0, the first major release of Spring Security since 4.0.0 in March 2015.
Spring Security started life in 2004 under the name Acegi, and is now led by Pivotal engineer Robert Winch, co-author of Packt’s Spring Security and the seminal book Spring Security 3.1. The 5.0.0 release contains over 400 enhancements and bug fixes, including support for OAuth 2.0, reactive support including Spring WebFlux and testing with project Reactor’s StepVerifier.
InfoQ spoke to Spring Security lead Rob Winch about the release and about the future.
InfoQ: The update site is pretty robust. Can you summarize the release?
Rob Winch: The highlights of Spring Security 5.0 include requiring a minimum of JDK 8, Reactive Security, OAuth 2.0 log-in (OIDC), and Modernized Password Storage.
InfoQ: How did you come up with the Modern Password Storage theme and implementation?
Winch: It is unfortunate, but before Spring Security 5.0 our default password storage was plain text which is not secure at all. Since this was a major release, this was our opportunity to switch to a more secure default.
Fortunately, we were able to work with John Steven who is an expert on password storage. In fact, he was one of the primary authors of the OWASP Password Storage Cheat Sheet. Spring Security now provides defaults that follow today's password storage recommendations. Even better, we can now passively update to different mechanisms.
InfoQ: The thing that impresses me most is how Spring always seems to deliver exactly what I was missing. How do you select and prioritize features?
Winch: We try and follow the community's lead by looking for highly voted issues and then develop a theme across the entire portfolio. This theme was updating to a minimum of JDK 8 and Reactive support using Project Reactor.
InfoQ: Are you going to be speeding up the release cycle for Spring Security, as Spring lead Juergen Hoeller described for Spring in general, releasing "what's ready" at shorter intervals?
Winch: Yes. Spring Security tries to follow the release cycle of Spring Framework to ensure that there is security for what Spring Framework is providing.
InfoQ: What's planned for the next release?
Winch: For our next release we plan to focus on refining both the Reactive and OAuth log-in support. We will also be providing hooks for migrating the way existing passwords are stored. We hope to release an initial version of OAuth Resource Server support as well.
Let's take a look at how Method Security has been enhanced (examples from the Spring Security website):
You can enable annotation-based security using the @EnableGlobalMethodSecurity
annotation on any @Configuration
instance to limit access to that method. For example, the following would enable Spring Security’s @Secured
annotation.
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class MethodSecurityConfig {
// ...
}
You can then apply appropriate method-level annotations:
public interface BankService {
@Secured("IS_AUTHENTICATED_ANONYMOUSLY")
public Account readAccount(Long id);
@Secured("IS_AUTHENTICATED_ANONYMOUSLY")
public Account[] findAccounts();
@Secured("ROLE_TELLER")
public Account post(Account account, double amount);
}
But sometimes you require more flexibility than GlobalMethodSecurity
provided. For those cases, Spring Security 5.0 introduces the ability to provide your own implementation by creating a config class that extends GlobalMethodSecurityConfiguration
and add an @EnableGlobalMethodSecurity
annotation on the config class.:
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
// ... create and return custom MethodSecurityExpressionHandler ...
return expressionHandler;
}
}
A feature of Reactor's reactive streams is that they allow for a single waiting thread to be allocated to new jobs, which introduces new challenges for implementing ThreadLocal type mappings. Reactor has responded with the reactive Context API, a kind of reactive ThreadLocal map.
In 5.0 you can access the reactive Context
via the static ReactiveSecurityContextHolder.getContext()
, which allows you to carry a security token (and other application-specific data) across method calls.