BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Spring Security 4.0: WebSocket, Spring Data and Test Support

Spring Security 4.0: WebSocket, Spring Data and Test Support

This item in japanese

The Spring Security team released Spring Security 4.0.0, adding several new features as well as more default security. Major themes include WebSocket Security, Spring Data integration, better testing support and the introduction of Spring Session as a new (Apache licensed) open source project. Spring Session simplifies the development of a custom backend as the HttpSession provider for your project. It allows developers to access a session from any environment, supports clustering, has a pluggable session-id strategy and supports websockets.

WebSocket Security
Spring Security now works with Spring's WebSocket support, but does not provide direct support for JSR-356 (Java API for WebSocket). To configure security on your websocket channels, you can use Spring's Java Configuration as follows.

@Configuration
public class WebSocketSecurityConfig
        extends AbstractSecurityWebSocketMessageBrokerConfigurer {

    protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
        messages.simpDestMatchers("/user/*").authenticated();
    }
}

Spring Data Integration
It is now possible to access the current user within Spring Data queries using SpEL. To enable this feature with Java Configuration, you can define a @Bean.

@Bean
public SecurityEvaluationContextExtension securityEvaluationContextExtension(){
    return new SecurityEvaluationContextExtension();
}

Then you can refer to Spring Security's principal in your queries. For example:

public interface BlogRepository extends JpaRepository<Blog,Long> {
    @Query("select blog from Blog blog where blog.user.login = ?#{principal.username}")
    List<Blog> findAllForCurrentUser();
}

Improved Testing Support
Spring Security 4.0 adds a number of annotations to simplify testing methods that require authentication. For example, if you have a method with @PreAuthorize("authenticated"), you can test it with the following mechanisms:

  • @WithMockUser: Adding it to a @Test method will run the test as a user with the username "user", the password "password", and the roles "ROLE_USER". You can override the these values by specifying parameters to the annotation: @WithMockUser(username="admin",roles={"USER","ADMIN"})
  • @WithUserDetails: Similar to @WithMockUser, but allows the Authentication principal to be customized, reducing the coupling to Spring Security.
  • @WithSecurityContext: Offers the most flexibility, allowing you to create your own custom testing annotations.

Spring Security 4.0 also works well with Spring MVC Test (4.1.3+). Below is an example where SecurityMockMvcConfigurers.springSecurity() performs all the setup to integrate the two frameworks.

import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@WebAppConfiguration
public class CsrfShowcaseTests {

    @Autowired
    private WebApplicationContext context;

    private MockMvc mvc;

    @Before
    public void setup() {
        mvc = MockMvcBuilders
                .webAppContextSetup(context)
                .apply(springSecurity())
                .build();
    }
…
}

Migrating from Spring Security 3.x to 4.x
The Spring Security team has published a migration guide for moving from Spring Security 3.x to 4.x. It includes instructions for migration XML configuration as well as Java configuration. Even better, it provides diff listings that highlight the required changes in a sample migration:

Spring Security 4.0 Java Configuration
The most basic Spring Security Java configuration creates a Servlet Filter, which is responsible for all the security (protecting URLs, validating credentials, redirecting to login, etc.). This involves several lines of code, but half of them are class imports.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.*;
import org.springframework.security.config.annotation.authentication.builders.*;
import org.springframework.security.config.annotation.web.configuration.*;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("user").password("password").roles("USER");
    }
}

There's not much code, but it provides many features:

  • Requires authentication to every URL in your application
  • Generates a login form for you
  • Allows user:password to authenticate with form based authentication
  • Allows the user to logout
  • CSRF attack prevention
  • Session Fixation protection
  • Security Header integration
    • HTTP Strict Transport Security for secure requests
    • X-Content-Type-Options integration
    • Cache Control
    • X-XSS-Protection integration
    • X-Frame-Options integration to help prevent Clickjacking
  • Integrates with HttpServletRequest API methods: getRemoteUser(), getUserPrinciple(), isUserInRole(role), login(username, password) and logout()

To use this release in a Spring Boot 1.2 project, you can override the Spring Security version as follows:

<properties>
    <spring-security.version>4.0.0.RELEASE</spring-security.version>
</properties>

To learn more about Spring Security 4.0, see Spring Security lead Rob Winch's presentation on InfoQ: From 0 to Spring Security 4.0. Slides from this presentation are available on SlideShare.

Rate this Article

Adoption
Style

BT