Spring安全 - httpbasic无法正常工作:我做错了什么?

时间:2016-10-01 14:17:04

标签: java spring spring-mvc spring-security

我对弹簧安全感到陌生。尝试将其用于带有休息后端的项目。对于我的后端,某些网址需要打开,某些网址需要httpbasic auth / https,某些网址需要令牌身份验证。

我尝试使用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!");
}

My Spring Security Config锁定如下:

@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身份验证。我的错误在哪里?

1 个答案:

答案 0 :(得分:3)

更改

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()...创建一个匹配每个网址的SecurityFilterChain。只要一个SecurityFilterChain与请求匹配,所有后续SecurityFilterChain将永远不会被评估。因此,您的FreeEndpointsConfig消耗了每个请求。

使用http.antMatcher("..."),您可以将每个SecurityFilterChain限制为特定的网址(模式)。现在FreeEndpointsConfig仅匹配/auth/signupHttpBasicAuthConfig /auth/login

小改进

您可以使用WebSecurity::configure制作多个网址,例如公开的静态资源(js,html或css)路径。覆盖WebSecurity::configure

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

并且不再需要FreeEndpointsConfig