Spring Security java配置 - 为什么选项顺序很重要?

时间:2015-09-05 19:11:42

标签: spring-security

我在过去的3-4天里第一次使用Spring Security(4.0.2),并且由于倾注了Spring Security样本,SO的众多帖子已经能够让它工作和其他博客。

但是,由于我已经尝试了不同的选项,因此在向HttpSecurity添加sessionManagement时,我被困了好几个小时。似乎选项的顺序很重要,我真的很好奇为什么会这样,以及为什么它似乎没有在Spring Security文档中的任何地方被提及,或者在其他任何我能找到的地方?

例如,如果先放置sessionManagement,那么下一个配置(在这种情况下为authorizeRequests,但下一个配置并不重要)会得到下面代码示例中注明的语法错误

@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);
}

看来sessionManagement必须是 last 配置。为什么?

此外,一旦我将sessionManagement放在最后,它就会使invalidSessionUrl方法的位置不同。我原来最后使用语法错误:

,如下所示
    .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

几个小时后,我发现invalidSessionUrl和maximumSessions是SessionManagementConfigurer的方法,expiredUrl和maxSessionsPreventsLogin属于SessionManagementConfigurer.ConcurrencyControlConfigurer,代码编译的唯一方法是将ConcurrencyControlConfigurer方法放在之后 SessionManagementConfigurer方法。

再一次,我真的很想知道为什么所以当我学习其他Spring接口时,我可以警惕这种事情。换句话说,我真的很想知道这里涉及到的架构设计或编程约定我还不知道是Spring的新手。

BTW,Rob Winch的网络研讨会非常有帮助!如果有人感兴趣,请点击这里链接:Webinar Replay: Spring Security 3.2

1 个答案:

答案 0 :(得分:2)

添加几个and(),它将编译:

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

一个缩进级别in表示新的返回类型(仅为了清晰起见)。 and()返回上一个类型。