Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Security java config - why does order of options matter?

I've spent the last 3-4 days working with Spring Security (4.0.2) for the first time and have been able to get it to work thanks to pouring over the Spring Security samples, numerous posts at SO and other blogs.

However, as I've been trying out different options I've was stumped for several hours with adding sessionManagement to HttpSecurity. It appears that the order of the options matters and I'm really curious why that is and why it doesn't seem to be mentioned anywhere in the Spring Security documentation, or anywhere else that I could find for that matter?

For example, if you place sessionManagement first then the next configuration (authorizeRequests in this case, but it doesn't matter which one is next) gets a syntax error noted in the code sample below

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
    .sessionManagement()
        .invalidSessionUrl("/login?invalid=1")
        .maximumSessions(1)
        .expiredUrl("/login?time=1")
        .maxSessionsPreventsLogin(true);
    .authorizeRequests()  //<<< The method authorizeRequests() is undefined for the type SecurityConfig
        .antMatchers("/", "/home", "/login**", "/thankyou").permitAll()
        .antMatchers("/admin/**").hasRole("ADMIN")
        .anyRequest().authenticated()
        .and()
    .formLogin()
        .loginPage("/login")
        .failureUrl("/login?err=1")
        .permitAll()
        .and()
    .logout()
        .logoutSuccessUrl("/thankyou")
        .deleteCookies( "JSESSIONID" )
        .invalidateHttpSession(false);
}

It appears sessionManagement must be the last config. Why?

Also, once I put sessionManagement last it made a different where the invalidSessionUrl method is placed. I originally had it last as shown below with the syntax error:

    .sessionManagement()
        .maximumSessions(1)
        .expiredUrl("/login?time=1")
        .maxSessionsPreventsLogin(true)
        .invalidSessionUrl("/login?invalid=1"); 
        //<<< The method invalidSessionUrl(String) is undefined for the type SessionManagementConfigurer<HttpSecurity>.ConcurrencyControlConfigurer

After a couple of hours I figured out that invalidSessionUrl and maximumSessions are methods of SessionManagementConfigurer and expiredUrl and maxSessionsPreventsLogin belong to SessionManagementConfigurer.ConcurrencyControlConfigurer and the only way the code will compile is if the ConcurrencyControlConfigurer methods are placed after the SessionManagementConfigurer methods.

Again, I'm would really like to know why so I can be alert to this sort of thing as I learn other Spring interfaces. In other words, I'd really like to know if there is an architectural design or programming convention involved here that I'm not yet aware of as a newbie to Spring.

BTW, the webinar by Rob Winch was super helpful! Here's the link if anyone is interested: Webinar Replay: Spring Security 3.2

like image 495
LWK69 Avatar asked Sep 05 '15 19:09

LWK69


1 Answers

Add a couple of and() and it will compile:

protected void configure(HttpSecurity http) throws Exception {
    http
    .sessionManagement()
        .invalidSessionUrl("/login?invalid=1")
        .maximumSessions(1)
            .expiredUrl("/login?time=1")
            .maxSessionsPreventsLogin(true)
            .and()
        .and()
    .authorizeRequests()
        ...

One indentation level in indicates a new return type (only for clarity). The and() returns to the previous type.

like image 157
holmis83 Avatar answered Oct 17 '22 16:10

holmis83