sno*_*lli 4 java spring spring-data spring-data-mongodb mockmvc
我正在尝试使用SpringBoot + Spring Data Mongo + SpringMVC运行一些集成测试
我已经简化和通用化了代码,但是它应该能够通过以下测试重现该行为。
从BookRepository界面中可以看到,我希望用户只能检索他拥有的书(@Query("{ 'ownerName' : '?#{principal?.username})),并且正在编写测试以执行POST来保存书,然后验证书的所有者是否设置正确。
出于此问题的目的,我已将测试简化为a GET,然后调用findAll()
执行任何MockMvc请求后,会SecurityContext被清除,ThreadLocalSecurityContextHolderStrategy#clearContext()这会导致在我尝试调用时引发以下异常repository.findAll();
java.lang.IllegalArgumentException: Authentication object cannot be null
@RepositoryRestResource
public interface BookRepository extends MongoRepository<Book, String> {
@Query("{ 'ownerName' : ?#{principal?.username} }")
List<Book> findAll();
}
Run Code Online (Sandbox Code Playgroud)
/**
* Integrate data mongo + mvc
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class BookCustomRepositoryIntegrationTest {
@Autowired
BookRepository repository;
@Autowired
MockMvc mockMvc;
@Test
@WithMockUser
public void reproduceBug() throws Exception {
repository.findAll(); //Runs allright
mockMvc.perform(get("/books")
.contentType(APPLICATION_JSON_UTF8))
.andExpect(status().isOk());
repository.findAll(); //Throws exception: java.lang.IllegalArgumentException: Authentication object cannot be null
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
您的情况不起作用,因为SecurityContextPersistenceFilter和FilterChainProxy过滤器清除了SecurityContextHolder,但是TestSecurityContextHolder(由填充WithSecurityContextTestExecutionListener)仍然包含SecurityContext。
试试这种方法:
@Test
@WithMockUser
public void reproduceBug() throws Exception {
repository.findAll();
mockMvc.perform(get("/books")
.contentType(APPLICATION_JSON_UTF8))
.andExpect(status().isOk());
SecurityContextHolder.setContext(TestSecurityContextHolder.getContext());
repository.findAll();
}
Run Code Online (Sandbox Code Playgroud)
AutoConfigureMockMvc我认为您可以配置而不是使用注释MockMvc注释,如下所示:
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*;\n\n@RunWith(SpringRunner.class)\n@SpringBootTest\npublic class BookCustomRepositoryIntegrationTest {\n\n @Before\n public void setup() {\n mockMvc = MockMvcBuilders\n .webAppContextSetup(context)\n .apply(springSecurity()) 1\n .build();\n }\n // ...\n}\nRun Code Online (Sandbox Code Playgroud)\n\n如文档所示所述:
\n\n\n\n为了将 Spring Security 与 Spring MVC Test 一起使用,有必要添加 Spring Security FilterChainProxy 作为过滤器。还需要添加 Spring Security\xe2\x80\x99s TestSecurityContextHolderPostProcessor 以支持在 Spring MVC Test with Annotations 中以用户身份运行。这可以使用 Spring Security\xe2\x80\x99s SecurityMockMvcConfigurers.springSecurity() 来完成。
\n
| 归档时间: |
|
| 查看次数: |
520 次 |
| 最近记录: |