2015-10-16 7 views
7

В моем проекте «Spring» я установил целевой URL-адрес выхода на «log logout» для отображения страницы входа с сообщением «Вы вышли из системы».Почему/login? Logout перенаправляет/login?

В конфигурации 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», но поскольку я больше не подключен, Spring Security хочет, чтобы я снова зашел в систему.

Когда я пытаюсь войти на страницу входа/выхода «log log» во время входа в систему, отображается хорошая страница.

Я нашел решение этой проблемы путем добавления этого:

  .authorizeRequests() 
      .antMatchers("/error","/login").permitAll() 

loginPage("/login").permitAll() Почему не сделать это? Я сделал что-то не так?

ответ

10

Почему не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?

При указании собственного 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"); 
    } 
}) 
+1

Наиболее отлично - мне удалось выяснить, большинство из этого, ползая по коду, но мне не хватало 'SecurityConfigurerAdapter'. Спасибо за ваш ответ, и мы увидим о щедрости через пару дней. –

+0

Хорошо - но есть Catch 22! Если задать пользовательский обработчик, Spring _resets_ URL. Если задать настраиваемый URL, Spring сбрасывает обработчик. Итак, в то время как «SecurityConfigurerAdapter» полезен; нет (если я что-то не упускаю), способ иметь пользовательский, скажем, обработчик ошибок, и иметь Spring автоматически сконфигурировать 'allowAll' правильно. Кроме того,' ExactUrlRequestMatcher' используется 'private', поэтому нельзя даже что-то сделать аналогично вручную ... –

+0

API ужасно хрупок, но я не уверен точно, о чем вы просите. Можете ли вы опубликовать свой сломанный код, и я попытаюсь решить его как мини-вопрос? Также укажите, если вы пытаетесь использовать 'DefaultLoginPageConfigurer' или у вас есть собственные шаблоны просмотров. – heenenee