0

我正在学习春假。我正在慢慢构建一个应用程序。我使用 TestRestTemplate 进行了完整的集成测试。
但是,我刚刚开始在我的应用程序中添加 Spring Security。从字面上看,只要我添加了 spring 安全依赖项,我的测试就会失败。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

我得到这样的错误:

Error while extracting response for type [class [Lcom.myproject.model.viewobjects.AView;] and content type [application/json]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `[Lcom.myproject.model.viewobjects.AView;` out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `[Lcom.myproject.model.viewobjects.AView;` out of START_OBJECT token
 at [Source: (PushbackInputStream); line: 1, column: 1]

当我调试时,它返回的尝试反序列化的对象为空。如果我在其余控制器上放置一个断点,它甚至不会到达那里。

似乎只是添加依赖项会打开很多默认值。如何在开启安全性的情况下进行测试?1)我可以以某种方式禁用测试的安全性吗?

2)我可以以某种方式不允许凭据或发送可接受的假凭据吗?(我确实看到了@WithMockUser 的示例,但这不适用于TestRestTemplate)

编辑:我尝试向我的测试类添加一个安全实现以启用匿名访问和允许:

@EnableWebSecurity
class TestSecurityConfig extends WebSecurityConfigurerAdapter
    {
    @Override
    protected void configure(HttpSecurity http) throws Exception
        {
        http.anonymous().and().authorizeRequests().antMatchers("/**").permitAll();
        }
    }

这样做的结果是 @GetMapping 工作。我可以追踪到呼叫到达控制器。但是@PostMapping 仍然不起作用。呼叫永远不会到达控制器。帖子调用如下所示:

updatedAView = restTemplate.postForObject(create_aview_url, aView, AView.class);

为什么会得到工作但不发帖???此外,为了确保没有其他问题,我再次删除了 spring-boot-starter-security 依赖项和所有相关代码。突然间一切正常。所以这绝对是安全配置。

4

1 回答 1

1

如果包含 spring-boot-starter-security 依赖项,则默认启用 spring security。TestRestTemplate 请求将通过安全系统进行处理。

如果您想在不进行身份验证的情况下进行测试,您可以使用 @EnableWebSecurity 配置 WebSecurityConfigurerAdapter 的版本,以便仅进行允许的测试。您可能需要排除其他配置,以免它们覆盖它。

这是一个例子:

@EnableWebSecurity
class TestSecurityConfig extends WebSecurityConfigurerAdapter
    {
    @Override
    protected void configure(HttpSecurity http) throws Exception
        {
        http.anonymous().and().csrf().disable().authorizeRequests().antMatchers("/**").permitAll();
        }
    }

这允许您在没有用户凭据的情况下发出请求

http.anonymous()

如果您不包括:

csrf().disable()

@GetMapping 将起作用,但没有 PostMapping 或更改数据的请求,因为这是当 csrf 发挥作用并且默认启用它时。

这允许您访问应用程序中的所有 URL。如果你愿意,你当然可以限制这个:

authorizeRequests().antMatchers("/**").permitAll()

于 2020-12-01T22:12:16.280 回答