我正在编写jUnit测试来测试我的资源服务器的端点。
现在,这些端点通过@PreAuthorized(和类似的)注解进行保护,如下所示:
@PreAuthorize("hasAuthority('SCOPE_data.write')")
@PostMapping("/save")
public ResponseEntity<Book> saveBook(
@io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "Save book",
required = true,
content = @Content(schema = @Schema(implementation = Book.class)))
@Valid @org.springframework.web.bind.annotation.RequestBody Book book){
try {
Book _book = bookRepo.save(new Book(book.getID(), vehicle.getTitle(), vehicle.getAuthor()));
return new ResponseEntity<>(_book, HttpStatus.CREATED);
}catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
我的单元测试应该是这样的:
@Test
public void testSaveBook() throws Exception {
this.mockMvc.perform(
post("/book/save")
.contentType(MediaType.APPLICATION_JSON)
.content(bookToSave))
.with(jwt().authorities(new SimpleGrantedAuthority("SCOPE_data.write")))
.andDo(print())
.andExpect(status().isOk));
}
这是我的SecurityConfig:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(exchanges -> exchanges
.antMatchers("/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html").permitAll()
.anyRequest().authenticated())
.csrf().disable()
.oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()));
return http.build();
}
我关心的是jwt()
指令。就像官方文档中写的那样,这条指令将创建一个带有**"headers" : { "alg" : "none" }
**的jwt令牌。
我的问题如下:
1.为什么我的端点可以使用此令牌访问?为什么我的资源服务器接受这个令牌?
2.有了这个令牌,任何用户都可以访问我的端点,从而访问数据库中的数据。
3.使用此令牌是否存在任何安全问题?
4.是否有任何过滤器可以插入FilterChain中?
有人能回答我的问题,消除我的疑虑吗?
谢谢.
1条答案
按热度按时间zsbz8rwp1#
MockMvc
测试DSL(特定于域的语言)中的jwt()
方法用于在测试中模拟JWT身份验证。下面我们来一一解答您的疑问:1.为什么我的端点可以使用此令牌访问?为什么我的资源服务器接受这个令牌?
当您在
MockMvc
测试的上下文中使用jwt().authorities(new SimpleGrantedAuthority("SCOPE_data.write"))
时,您实际上是创建了一个模拟(模拟)的JWT身份验证来进行测试。它绕过了正常的JWT处理和验证(签名、过期、颁发者等),直接模拟使用具有给定权限的JWT进行身份验证的用户。只是为了测试在实际场景中,实际的JWT将根据资源服务器的配置进行处理和验证。1.使用此令牌,任何用户都可以访问我的端点并因此访问数据库中的数据吗?
不可以,真实的用户不能使用“alg:在生产环境中使用“none”令牌来访问端点。这是一种只在
MockMvc
框架范围内有效的测试机制。在生产中,令牌将被拒绝,因为它是未签名的。值得注意的是,在真实的的JWT处理中允许“none”作为算法是一种安全风险,但这不是这里发生的事情。这仅适用于测试场景。1.使用此令牌是否存在任何安全问题?
只要这个模拟的JWT身份验证严格地在测试环境的范围内使用,而不是在生产环境中使用,就不应该有安全问题。这是Spring Security提供的用于测试目的的实用程序。你基本上是在说,“让我们假设我们有一个有效的JWT与这些权威,看看系统的行为。”
但是,一些最佳实践和附加说明:
最后,当您的测试正在检查
status().isOk
时,实际端点在保存一本书时返回HttpStatus.CREATED
(201)。您可能希望更新测试以检查status().isCreated()
而不是isOk()
,从而更准确地反映预期行为。