gpt4 book ai didi

spring - 模拟 SecurityContextHolder/Authentication 总是返回 null

转载 作者:行者123 更新时间:2023-12-05 00:51:03 26 4
gpt4 key购买 nike

我知道这个问题经常被问到,但也许我有一些特别的事情。我正在尝试对支持 REST(不是 Spring MVC)的 Spring Boot 应用程序进行一些集成测试,出于某种原因 SecurityContextHolder.getContext().getAuthentication()即使使用 @WithMockUser 也总是返回 null在测试中。我不确定这是否与在配置类上使用配置文件有关,但到目前为止我们还没有遇到任何问题。

类(class)

@Override
public ResponseEntity<EmployeeDTO> meGet() {
Principal principal = SecurityContextHolder.getContext().getAuthentication();
logger.debug("Endpoint called: me({})", principal);
EmployeeDTO result;

// Get user email from security context
String email = principal.getName(); // NPE here

// ...
}

测试
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = {"eureka.client.enabled:false"})
@WithMockUser
@ActiveProfiles(value = "test")
public class MeControllerTest extends IntegrationSpringBootTest {

@Autowired
private TestRestTemplate restTemplate;

@MockBean
private SecurityContext securityContext;

@MockBean
private Authentication authentication;

@MockBean
private EmployeeRepository employeeRepository;

@BeforeClass
public static void setUp() {

}

@Before
@Override
public void resetMocks() {
reset(employeeRepository);
}

@Test
public void meGet() throws Exception {
when(securityContext.getAuthentication()).thenReturn(authentication);
securityContext.setAuthentication(authentication);
when(authentication.getPrincipal()).thenReturn(mockEmployee());
SecurityContextHolder.setContext(securityContext);
when(employeeRepository.findByEmail(anyString())).thenReturn(mockEmployee());

ResponseEntity<EmployeeDTO> employeeDTOResponseEntity =
this.restTemplate.getForEntity("/me", EmployeeDTO.class);
// ...
}

如果我返回一个模拟 Principal而不是 mockEmployee()测试甚至无法开始,因为发生这种情况:
org.springframework.beans.factory.BeanCreationException: Could not inject field: private org.springframework.security.core.Authentication com.gft.employee.controller.MeControllerTest.authentication; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'org.springframework.security.core.Authentication#0' is expected to be of type 'org.springframework.security.core.Authentication' but was actually of type '$java.security.Principal$$EnhancerByMockitoWithCGLIB$$657040e6'

附加说明:此 Spring Boot 应用程序也使用 OAuth2 进行授权,但必须将其关闭以进行这些测试。这就是我们使用配置文件的原因。省略 @ActiveProfiles注释为我们提供了针对端点请求的 401 Unauthorized 错误。

我可以使用 PowerMock,但如果可能的话,我想避免使用它。

最佳答案

为身份验证 SecurityContextHolder 编写 Junit 的更简单方法是模拟它们。以下是它的工作实现。
您可以根据需要添加模拟类,然后设置 SecurityContextHolder 的上下文,然后使用 when() 进一步模拟并返回适当的模拟值。

    AccessToken mockAccessToken = mock(AccessToken.class);
Authentication authentication = mock(Authentication.class);
SecurityContext securityContext = mock(SecurityContext.class);

when(securityContext.getAuthentication()).thenReturn(authentication);

SecurityContextHolder.setContext(securityContext);

when(SecurityContextHolder.getContext().getAuthentication().getDetails()).thenReturn(mockSimpleUserObject);

关于spring - 模拟 SecurityContextHolder/Authentication 总是返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44849827/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com