Spring WebMvcTest 如何模拟身份验证? [英] Spring WebMvcTest how to mock Authentication?

查看:34
本文介绍了Spring WebMvcTest 如何模拟身份验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用以下方法的控制器.我从方法参数中获取 Authentication 并使用它来获取主体.

I have a controller with the following method. I get the Authentication from the method parameters and use it to get the principal.

@PatchMapping("/{employeeId}/present")
public PersonalDevelopmentPlan savePresent(@PathVariable int employeeId,
                                           @RequestBody PersonalDevelopmentPlan personalDevelopmentPlan,
                                           Authentication authentication) {
    EmployeeDetails details = (EmployeeDetails) authentication.getPrincipal();
    return pdpService.savePresent(employeeId, personalDevelopmentPlan, details.getEmployee().getId());
}

然后我使用 @WebMvcTest

@Test
@WithMockUser
public void testSavePresent_returns_result_from_service() throws Exception {

    PersonalDevelopmentPlan pdp = new PersonalDevelopmentPlan();
    pdp.setEmployee(EMPLOYEE_ID);

    given(service.savePresent(eq(EMPLOYEE_ID), any(), anyInt())).willReturn(pdp);

    mvc.perform(patch(URL_WITH_ID + "/present").secure(true)
            .contentType(MediaType.APPLICATION_JSON)
            .content(objectMapper.writeValueAsString(pdp)))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.employee", Matchers.is(EMPLOYEE_ID)));
}

当我运行这个时,我在下面一行得到一个 NullPointerException:

When i run this though, i get a NullPointerException on the following line:

EmployeeDetails details = (EmployeeDetails) authentication.getPrincipal();

因为身份验证为空.我已经用 @MockUser 注释了测试,但身份验证仍然为空.如何在控制器方法的参数中模拟身份验证?

Because authentication is null. I already annotated the test with @MockUser but still authentication is null. How do i mock authentication in the parameters of the controller method?

我的测试用 @AutoConfigureMockMvc(addFilters = false)

谢谢!

推荐答案

@WithMockUser这将使用 Authentication 上的主体是 Spring Security 的 User 对象

@WithMockUser This will use the principal on the Authentication is Spring Security’s User object

@WithUserDetails

虽然 @WithMockUser 是一种非常方便的入门方式,但它可能并非在所有情况下都有效.例如,应用程序通常期望 Authentication 主体为特定类型.这样做是为了让应用程序可以将主体引用为自定义类型并减少对 Spring Security 的耦合.

While @WithMockUser is a very convenient way to get started, it may not work in all instances. For example, it is common for applications to expect that the Authentication principal be of a specific type. This is done so that the application can refer to the principal as the custom type and reduce coupling on Spring Security.

自定义主体通常由自定义 UserDetailsS​​ervice 返回,该自定义UserDetailsS​​ervice 返回实现 UserDetails 和自定义类型的对象.对于这种情况,使用自定义 UserDetailsS​​ervice 创建测试用户很有用.这正是 @WithUserDetails 所做的.

The custom principal is often times returned by a custom UserDetailsService that returns an object that implements both UserDetails and the custom type. For situations like this, it is useful to create the test user using the custom UserDetailsService. That is exactly what @WithUserDetails does.

@WithSecurityContext

我们可以创建自己的注解,使用@WithSecurityContext 创建我们想要的任何 SecurityContext.例如,我们可以创建一个名为 @WithMockCustomUser 的注解为 @WithSecurityContext(factory = WithMockCustomUserSecurityContextFactory.class)

We can create our own annotation that uses the @WithSecurityContext to create any SecurityContext we want. For example, we might create an annotation named @WithMockCustomUser as @WithSecurityContext(factory = WithMockCustomUserSecurityContextFactory.class)

这篇关于Spring WebMvcTest 如何模拟身份验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆