我在过去的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答案 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()
返回上一个类型。