为什么/ login?logout重定向到/ login?

时间:2015-10-16 09:58:58

标签: java spring spring-security

在我的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()这样做? 我做错了吗?

1 个答案:

答案 0 :(得分:14)

为什么不 loginPage("/login").permitAll() 允许访问 /login?logout

因为当您在permitAll或大多数其他配置工具上FormLoginConfigurer时,它只允许访问exact URLs

那么,为什么 authorizeRequests().antMatchers("/login").permitAll() 允许访问呢?

因为它使用AntPathRequestMatchermatches 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>

当您指定自己的logoutSuccessHandlerlogoutSuccessUrl时,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");
    }
})