2016-10-01 92 views
0

我是新來的春季安全。嘗試將它用於具有休息後端的項目。對於我的後端,某些網址需要打開,某些網址需要httpbasic auth/https和某些網址需要令牌認證。春季安全 - httpbasic不工作:我做錯了什麼?

我試圖用web mvc測試來設置它。嘗試使用控制器的方法來測試它:

@RequestMapping(value="/auth/signup", method=RequestMethod.POST) 
@ResponseStatus(HttpStatus.OK) 
public void test(){ 
    System.err.println("Controller reached!"); 
} 

@RequestMapping(value="/auth/login", method=RequestMethod.POST) 
@ResponseStatus(HttpStatus.OK) 
public void test2(){ 
    System.err.println("Controller reached!"); 
} 

我的春季安全配置鎖類似如下:

@EnableWebSecurity 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

@Autowired 
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
    auth 
     .inMemoryAuthentication() 
      .withUser("user").password("password").roles("USER"); 
} 

@Configuration 
@Order(1) 
public static class FreeEndpointsConfig extends WebSecurityConfigurerAdapter { 
    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.authorizeRequests().antMatchers("/auth/signup").permitAll() 
     .and().csrf().disable(); 
    } 
} 

@Configuration 
@Order(2) 
public static class HttpBasicAuthConfig extends WebSecurityConfigurerAdapter { 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.authorizeRequests().antMatchers("/auth/login").hasAnyRole("USER") 
     .and().httpBasic() 
     .and().csrf().disable(); 
    } 
} 
} 

我的測試是這樣的:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes={RootContext.class, WebSecurityConfig.class}) 
@WebAppConfiguration 
public class AccountSecurityTest { 

@Autowired 
private WebApplicationContext wac; 

private MockMvc securityMockMvc; 

@Before 
public void SetupContext() {  
    securityMockMvc = MockMvcBuilders 
      .webAppContextSetup(wac) 
      .apply(springSecurity()).build(); 
} 

@Test 
public void testSigInFree() throws Exception { 
    MockHttpServletRequestBuilder post = post("/auth/signup"); 
    securityMockMvc.perform(post).andExpect(status().isOk()); 
} 

@Test 
public void testLoginHttpBasic() throws Exception { 
    MockHttpServletRequestBuilder post = post("/auth/login"); 
    securityMockMvc.perform(post).andExpect(status().isOk()); 
} 
} 

的TestMethod的 「testLoginHttpBasic」是綠色的。但我期望失敗,因爲我試圖配置/強制httpbasic身份驗證。我的錯誤在哪裏?

+0

這似乎是Spring Security的默認行爲,它只是在響應中包含一個標頭,告訴瀏覽器在登錄失敗時再次顯示登錄表單。您也可以在瀏覽器中輕鬆測試它。我認爲這不會讓人誤解,因爲你正在測試一個控制器,這個控制器應該被最終用戶訪問。所以當你開發一個真正的登錄表單時,當用戶登錄失敗時,響應不會是401,但是你會將他重定向到登錄失敗頁面。 –

回答

1

變化

http.authorizeRequests().antMatchers("/auth/signup").permitAll()http.antMatcher("/auth/signup").authorizeRequests().anyRequest().permitAll()

http.antMatcher("/auth/login").authorizeRequests().anyRequest().hasAnyRole("USER")http.authorizeRequests().antMatchers("/auth/login").hasAnyRole("USER")

您的第二個測試將失敗。

爲什麼你需要這個改變?

http.authorizeRequests()...創建一個匹配每個URL的SecurityFilterChain。只要一個SecurityFilterChain匹配請求,所有後續SecurityFilterChain將永遠不會被評估。因此,您的FreeEndpointsConfig消耗了每個請求。

隨着http.antMatcher("...")到位,您將每個SecurityFilterChain限制爲特定的URL(模式)。現在FreeEndpointsConfig只匹配/auth/signupHttpBasicAuthConfig/auth/login

小的改進

你可以讓多個URL像路徑靜態資源(JS,HTML或CSS)公共可用WebSecurity::configure。在WebSecurityConfig

@Override 
public void configure(WebSecurity webSecurity) throws Exception { 
    webSecurity 
      .ignoring() 
      .antMatchers("/auth/signup"); 
} 

FreeEndpointsConfig時不再需要重寫WebSecurity::configure