在我的Spring项目中,我将注销目标网址设置为“/ login?logout”以显示登录页面,并显示消息“您现在已注销”。
在Spring Security配置中,我这样做了:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/error").permitAll()
.anyRequest().fullyAuthenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.successHandler(loginSuccessHandler)
.failureUrl("/login?error")
.and()
.httpBasic()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.permitAll()
.logoutSuccessHandler(logoutSuccessHandler);
}
和logoutSuccessHandler:
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
if (authentication != null) {
Log.debug(authentication.getName() + " LOGOUT !!");
}
setDefaultTargetUrl("/login?logout");
super.onLogoutSuccess(request, response, authentication);
}
当我尝试注销时,我到达“/ login”页面(没有?logout)。 我不明白为什么它会在这个页面上重定向我。
我认为该应用程序试图将我重定向到“/ login?logout”,但由于我已不再连接,因此Spring安全性要求我再次登录。
当我在登录时尝试访问“/ login?logout”页面时,它会显示正常页面。
我通过添加以下内容找到了解决此问题的方法:
.authorizeRequests()
.antMatchers("/error","/login").permitAll()
为什么没有loginPage("/login").permitAll()
这样做?
我做错了吗?
答案 0 :(得分:14)
为什么不 loginPage("/login").permitAll()
允许访问 /login?logout
?
因为当您在permitAll
或大多数其他配置工具上FormLoginConfigurer
时,它只允许访问exact URLs。
那么,为什么 authorizeRequests().antMatchers("/login").permitAll()
允许访问呢?
因为它使用AntPathRequestMatcher
,matches on the request path only和路径does not contain the query string。
但我知道我已经看过代码,可以让我访问 /login?logout
而根本没有明确的 permitAll
。怎么了?
Spring Security喜欢提供“明智的”默认设置,并且如果没有指定,则认为提供默认登录和注销页面是“明智的”。默认的注销页面是/login?logout
,因此如果您不指定任何内容,则可以使用它。这是由DefaultLoginPageGeneratingFilter
完成的,它会自动生成一些HTML和short-circuits URL authorization。
那么,当我指定 /login?logout
时,为什么我会失去对默认 logoutSuccessHandler
页面的访问权限? < / p>
当您指定自己的logoutSuccessHandler
或logoutSuccessUrl
时,Spring Security会假定您提供自己的注销视图,因此它不会将DefaultLoginPageGeneratingFilter
初始化为短路URL授权。注销页面,并希望您自己配置自己的视图授权。
但我想保留默认的退出页面。我只是想添加一些自定义的额外处理。我不能这样做吗?
如果您想指定自己的logoutSuccessHandler
但仍保留默认的/login?logout
视图,则必须告诉DefaultLoginPageGeneratingFilter
仍然继续提供该视图。您可以使用自定义SecurityConfigurer
执行此操作,如下所示:
.logoutSuccessHandler(logoutSuccessHandler)
.and()
.apply(new SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity>() {
@Override public void configure(HttpSecurity builder) throws Exception {
builder.getSharedObject(DefaultLoginPageGeneratingFilter.class).setLogoutSuccessUrl("/login?logout");
}
})