2016-03-04 94 views
0

我有一個簡單的Gradle Spring Boot(v 1.3.3)WebMVC應用程序,我通過命令行通過「Gradle bootrun」運行。我還包括Spring Security,並通過包含一個java安全配置類來重寫某些默認安全配置。我的構建文件logoutSuccessUrl不能在Spring Boot中工作

buildscript { 
    ext { 
     springBootVersion = '1.3.3.RELEASE' 
    } 
    repositories { 
     mavenCentral() 
    } 
    dependencies { 
     classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") 
    } 
} 

apply plugin: 'java' 
apply plugin: 'eclipse' 
apply plugin: 'spring-boot' 

jar { 
    baseName = 'readinglist' 
    version = '0.0.1-SNAPSHOT' 
} 
sourceCompatibility = 1.8 
targetCompatibility = 1.8 

repositories { 
    mavenCentral() 
} 

dependencies { 
    compile('org.springframework.boot:spring-boot-starter-data-jpa') 
    compile('org.springframework.boot:spring-boot-starter-thymeleaf') 
    compile('org.springframework.boot:spring-boot-starter-web') 
    compile("org.springframework.boot:spring-boot-starter-security") 
    runtime('com.h2database:h2') 
    testCompile('org.springframework.boot:spring-boot-starter-test') 
} 

eclipse { 
    classpath { 
     containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER') 
     containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8' 
    } 
} 

task wrapper(type: Wrapper) { 
    gradleVersion = '2.9' 
} 

我的安全配置類是

package readinglist; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 
import org.springframework.security.config.annotation.web.builders.HttpSecurity; 
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 
import org.springframework.security.core.userdetails.UserDetails; 
import org.springframework.security.core.userdetails.UserDetailsService; 
import org.springframework.security.core.userdetails.UsernameNotFoundException; 

@Configuration 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private ReaderRepository readerRepository; 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
    http 
     .authorizeRequests() 
     .antMatchers("/readingList").access("hasRole('READER')") 
     .antMatchers("/**").permitAll() 
     .and() 
     .formLogin() 
     .loginPage("/login") 
     .failureUrl("/login?error=true") 
     .and() 
     .logout() 
      .logoutSuccessUrl("/"); // Added .and()....logoutSuccessURL() 
    } 

    @Override 
    protected void configure(
       AuthenticationManagerBuilder auth) throws Exception { 
    auth 
     .userDetailsService(new UserDetailsService() { 
     @Override 
     public UserDetails loadUserByUsername(String username) 
      throws UsernameNotFoundException { 
      UserDetails userDetails = readerRepository.findOne(username); 
      if (userDetails != null) { 
      return userDetails; 
      } 
      throw new UsernameNotFoundException("User '" + username + "' not found."); 
     } 
     }); 
    } 

} 

我也有家庭控制器的URL「/」映射到視圖home.html的 當我運行應用程序,並去到localhost:8080 /我得到了主頁。 當我嘗試訪問URL「/ readingList」時,我得到了自定義登錄頁面。如果我輸入的憑據不正確,我會返回登錄頁面進行另一次嘗試。如果我輸入有效的憑證,我會得到readingList頁面。到現在爲止還挺好。問題出在logoutSuccessURL(「/」)。當我去「/註銷」的URL這應該註銷了我,並帶我回到「/」,而是我得到在瀏覽器中顯示以下錯誤:

Whitelabel Error Page 

This application has no explicit mapping for /error, so you are seeing this as a fallback. 
Thu Mar 03 19:31:24 PST 2016 
There was an unexpected error (type=Not Found, status=404). 
No message available 

我打開調試的安全和當我打我的註銷鏈接我得到如下:

2016-03-03 19:48:45.033 DEBUG 22401 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet  : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/error] 
2016-03-03 19:48:45.033 DEBUG 22401 --- [io-8080-exec-10] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /error 
2016-03-03 19:48:45.036 DEBUG 22401 --- [io-8080-exec-10] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)] 
2016-03-03 19:48:45.036 DEBUG 22401 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet  : Last-Modified value for [/error] is: -1 
2016-03-03 19:48:45.046 DEBUG 22401 --- [io-8080-exec-10] o.s.w.s.v.ContentNegotiatingViewResolver : Requested media types are [text/html, text/html;q=0.8] based on Accept header types and producible media types [text/html]) 
2016-03-03 19:48:45.047 DEBUG 22401 --- [io-8080-exec-10] o.s.w.s.v.ContentNegotiatingViewResolver : Returning [org.springfram[email protected]7ae1a0fb] based on requested media type 'text/html' 
2016-03-03 19:48:45.047 DEBUG 22401 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet  : Rendering view [org.springfram[email protected]7ae1a0fb] in DispatcherServlet with name 'dispatcherServlet' 
2016-03-03 19:48:45.055 DEBUG 22401 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet  : Successfully completed request 

我不知道爲什麼的DispatcherServlet正試圖查找「/錯誤」。我也沒有被註銷,因爲如果我嘗試再次訪問URL「/ readingList」,我不會提示輸入憑據。

我在loggin中做了一些測試,然後手動轉到URL「/ logout」。我在我的日誌中得到以下內容:

2016-03-04 16:39:31.170 DEBUG 24395 --- [nio-8080-exec-6] o.s.security.web.FilterChainProxy  : /logout reached end of additional filter chain; proceeding with original chain 
2016-03-04 16:39:31.170 DEBUG 24395 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet  : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/logout] 
2016-03-04 16:39:31.170 DEBUG 24395 --- [nio-8080-exec-6] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /logout 
2016-03-04 16:39:31.171 DEBUG 24395 --- [nio-8080-exec-6] s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/logout] 
2016-03-04 16:39:31.171 DEBUG 24395 --- [nio-8080-exec-6] o.s.w.s.handler.SimpleUrlHandlerMapping : Matching patterns for request [/logout] are [/**] 
2016-03-04 16:39:31.171 DEBUG 24395 --- [nio-8080-exec-6] o.s.w.s.handler.SimpleUrlHandlerMapping : URI Template variables for request [/logout] are {} 
2016-03-04 16:39:31.172 DEBU    G 24395 --- [nio-8080-exec-6] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapping [/logout] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/]], resolvers=[[email protected]46f93]]] and 1 interceptor 
2016-03-04 16:39:31.172 DEBUG 24395 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet  : Last-Modified value for [/logout] is: -1 
2016-03-04 16:39:31.172 DEBUG 24395 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet  : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling 
2016-03-04 16:39:31.173 DEBUG 24395 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet  : Successfully completed request 
2016-03-04 16:39:31.173 DEBUG 24395 --- [nio-8080-exec-6] o.s.s.w.a.ExceptionTranslationFilter  : Chain processed normally 
2016-03-04 16:39:31.173 DEBUG 24395 --- [nio-8080-exec-6] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed 
2016-03-04 16:39:31.196 DEBUG 24395 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet  : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/error] 
.... 

看起來像「/註銷」的URL不工作,我不承認。我雖然默認的註銷URL是「/註銷」。

+0

'/ logout'默認只與POST一起工作..所以只有去'/ logout'不會起作用,因爲那是GET而不是POST。要使它與GET一起工作,您需要禁用CSFR保護(默認情況下啓用)。 –

+0

這肯定是Spring Security在某些時候的變化。正如我所說,我有一些其他的Spring Security項目,我設置/註銷,並且不必禁用CSRF,或者使用logoutRequestMatcher(...)將其設置爲POST或POST/GET。 –

+0

在Spring Security 4中,過濾器在默認情況下在早期版本中啓用,它們僅在使用java config時啓用。 –

回答

1

我在這裏找到了一個類似項目的解決方案,http://spr.com/part-5-integrating-spring-security-with-spring-boot-web/。在我的安全配置,我改變

.logout() 
    .logoutSuccessUrl("/") 
    .and() 
    ... 

.logout() 
    .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) 
     .logoutSuccessUrl("/") 
     .and() 
     ... 

我不知道這是否是「首選」解決方案,我不知道爲什麼調用logoutRequestMatcher(... )是必要的。我有其他(非Spring-Boot)Spring Security項目,它們不使用對logoutRequestMatcher(...)的調用,而.logout(...)。logoutSuccessUrl(...)調用工作得很好。

0
  .and()  
      .logout() 
      .invalidateHttpSession(true) 
      .logoutUrl("/logout") 
      .permitAll(); 

我喜歡這個解決方案,因爲它擦拭會話數據,所以你不能訪問了嘗試yousrself,以確保在瀏覽器中打開的開發工具和看到會話!

+0

你讀過我的回答了嗎? –

相關問題