我是 Spring Security 的新手。尝试将其用于具有休息后端的项目。对于我的后端,某些 url 需要打开,某些 url 需要具有 httpbasic auth/https,某些 url 需要 token 身份验证。
我正在尝试使用 Web MVC 测试来设置它。尝试使用 Controller 方法来测试它:
@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 配置锁定如下:
@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 身份验证。我的错误在哪里?
最佳答案
改变
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/signup
和 HttpBasicAuthConfig
/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
。
关于java - Spring安全-httpbasic不工作: What am i doing wrong?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39807676/