2015-10-16 17 views
7

W moim projekcie wiosennym ustawiam adres docelowy wylogowania na "/ login? Logout", aby wyświetlić stronę logowania z komunikatem "Wylogowano się".Dlaczego/login? Wyloguj się przekierowanie do/login?

w config wiosny Bezpieczeństwa, zrobiłem to:

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

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

Podczas próby wylogowania, przyjadę na stronie "/ login" (bez ?Wyloguj). Nie rozumiem, dlaczego przekierowuje mnie na tę stronę.

Myślę, że aplikacja próbuje przekierować mnie na "/ login? Logout", ale ponieważ nie jestem już połączony, Spring Security chce, żebym się ponownie zalogował.

Kiedy próbuję uzyskać dostęp do strony "/ login? Logout", gdy jestem zalogowany, wyświetla się dobra strona.

Znalazłem rozwiązanie tego problemu, dodając w ten sposób:

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

Dlaczego nie loginPage("/login").permitAll() to zrobić? Czy zrobiłem coś złego?

Odpowiedz

10

Dlaczego nieloginPage("/login").permitAll()umożliwić dostęp do/login?logout?

Bo kiedy robisz permitAll na FormLoginConfigurer lub większość innych narzędzi systemowych dla tej sprawy, pozwoli to dostęp do tych exact URLs tylko.

Cóż, dlaczegoauthorizeRequests().antMatchers("/login").permitAll()umożliwić dostęp wtedy?

Ponieważ to używa AntPathRequestMatcher, który matches on the request path only, a ścieżka does not contain the query string.

Ale wiem, widziałem kod, który umożliwia mi dostęp/login?logoutbez wyraźnejpermitAllw ogóle. Co z tym?

Spring Security lubi zapewniać "rozsądne" wartości domyślne i uważa, że ​​"rozsądne" jest dostarczanie domyślnych stron logowania i wylogowania, jeśli żadna z nich nie jest określona. Domyślna strona wylogowania to /login?logout, więc możesz jej użyć, jeśli nic nie określisz. Robi to DefaultLoginPageGeneratingFilter, który automatycznie generuje HTML i short-circuits URL authorization.

Więc dlaczego mam stracić dostęp do domyślnego/login?logoutstronę kiedy podaćlogoutSuccessHandler?

Po określeniu własnego logoutSuccessHandler lub logoutSuccessUrl, Wiosna bezpieczeństwa zakłada, że ​​dostarczają swoje własne poglądy wylogowania, więc nie ma zainicjować DefaultLoginPageGeneratingFilter do zwarcia autoryzacji URL na stronie wylogowania i oczekuje skonfigurowanie zezwolenia na własnych poglądach.

Ale chcę zachować domyślną stronę wylogowania. Chcę tylko dodać niestandardową dodatkową obsługę. Nie mogę tego po prostu zrobić?

Jeśli chcesz określić własną logoutSuccessHandler ale nadal pozostawić domyślną /login?logout pogląd, trzeba powiedzieć DefaultLoginPageGeneratingFilter aby nadal zachować zapewniając jej. Można to zrobić z niestandardowych SecurityConfigurer, co następuje:

.logoutSuccessHandler(logoutSuccessHandler) 
.and() 
.apply(new SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity>() { 
    @Override public void configure(HttpSecurity builder) throws Exception { 
     builder.getSharedObject(DefaultLoginPageGeneratingFilter.class).setLogoutSuccessUrl("/login?logout"); 
    } 
}) 
+1

Najbardziej doskonałe - udało mi się wyjaśnić większość to poprzez indeksowanie poprzez kod, ale brakowało mi 'SecurityConfigurerAdapter'. Dziękuję za odpowiedź, a za kilka dni zobaczymy nagrodę za bounty. –

+0

Dobra - ale jest Catch 22! Jeśli ustawi się procedurę obsługi niestandardowej, Spring _resets_ URL. Jeśli ustawi się niestandardowy adres URL, Spring zresetuje procedurę obsługi. Tak więc, chociaż "SecurityConfigurerAdapter" jest przydatny; nie ma (chyba, że ​​czegoś brakuje) sposobu na posiadanie niestandardowego, powiedzmy, obsługi niepowodzeń, i wiosennego autokonfigurowania poprawnie 'allowAll', Dalej,' ExactUrlRequestMatcher' używany jest 'prywatny', więc nie można nawet zrobić czegoś analogiczny ręcznie ... –

+0

Interfejs API jest strasznie kruchy, ale nie jestem do końca pewien, o co prosisz. Czy możesz opublikować swój uszkodzony kod, a postaram się odpowiedzieć na to pytanie jako mini-pytanie? Proszę również określić, czy próbujesz użyć 'DefaultLoginPageConfigurer' lub masz własne szablony widoku. – heenenee

Powiązane problemy