【问题标题】:Spring security - httpbasic not working: What am i doing wrong?Spring security - httpbasic 不起作用:我做错了什么?
【发布时间】:2017-02-09 23:39:15
【问题描述】:

我是 Spring Security 的新手。尝试将它用于带有休息后端的项目。对于我的后端,某些 url 需要打开,某些 url 需要具有 httpbasic auth / https 并且某些 url 需要令牌身份验证。

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

我的 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());
}
}

测试方法“testLoginHttpBasic”是绿色的。但我预计会失败,因为我正在尝试配置/强制执行 httpbasic 身份验证。我的错误在哪里?

【问题讨论】:

  • 这似乎是 Spring Security 的默认行为,它只是在响应中包含一个标头,告诉浏览器在登录失败时再次显示登录表单。您也可以在浏览器中轻松测试它。我认为这不会产生误导,因为您正在测试一个旨在由最终用户访问的控制器。因此,当您开发一个真正的登录表单时,当用户登录失败时,响应不会是 401,但您会将他重定向到登录失败页面。

标签: java spring spring-mvc spring-security


【解决方案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 匹配请求,就永远不会评估所有后续SecurityFilterChains。因此,您的 FreeEndpointsConfig 消耗了每个请求。

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

小改进

您可以使用WebSecurity::configure 公开多个 URL,例如静态资源(js、html 或 css)的路径。在您的 WebSecurityConfig 中覆盖 WebSecurity::configure

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

并且不再需要FreeEndpointsConfig

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-13
    • 1970-01-01
    • 1970-01-01
    • 2013-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多