Spring 安全,JUnit:@Before 中创建的用户的@WithUserDetails
Spring Security, JUnit: @WithUserDetails for user created in @Before
在使用 Spring MockMVC 的 JUnit 测试中,有两种方法可以作为 Spring 安全用户进行身份验证:@WithMockUser
使用提供的凭据创建一个虚拟用户,@WithUserDetails
获取用户名并使用自定义 UserDetailsService
(UserDetailsServiceImpl
)将其解析为正确的自定义 UserDetails
实现。
在我的例子中,UserDetailsService
从数据库加载一个用户。我要使用的用户已插入到测试套件的 @Before
方法中。
但是,我的UserDetailsServiceImpl
没有找到用户。
在我的 @Before
中,我这样插入用户:
User u = new User();
u.setEMail("test@test.de");
u = userRepository.save(u);
并且在 UserDetailsServiceImpl
中:
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = this.userRepository.findOneByEMail(username);
if (user == null)
throw new UsernameNotFoundException(String.format("No user found with username '%s'.", username));
return user;
}
如何将在 @Before
中创建的帐户用于 @WithUserDetails
?
不幸的是,您无法使用 @Before
轻松完成 @WithUserDetails
,因为 Spring @WithUserDetails
注释将在 [之前调用 Spring 安全上下文测试侦听器=22=] setUp
方法与 @Before
.
这里是一个小技巧和对你问题的回答。
@Inject
private EntityManager em;
@Inject
PlatformTransactionManager txManager;
@BeforeTransaction
public void setup() {
new TransactionTemplate(txManager).execute(status -> {
User u = new User();
u.setEMail("test@test.de");
em.save(u);
return null;
});
}
@AfterTransaction
public void cleanup() {
new TransactionTemplate(txManager).execute(status -> {
// Check if the entity is managed by EntityManager.
// If not, make it managed with merge() and remove it.
em.remove(em.contains(u) ? user1 : em.merge(u));
return null;
});
}
@Test
@Transactional
@WithUserDetails(value = "test@test.de", userDetailsServiceBeanName = "loadUserByUsername")
public void test() {
}
您可以使用 @PostConstruct
而不是 @Before
。那对我有用。有人可以证实吗?
使用setupBefore = TEST_EXECUTION
这将有效地导致 @WithUserDetails
在 @Before
和 @BeforeEach
之后执行
@BeforeEach
public void createUser() {
...
}
@Test
@WithUserDetails(value = "username", setupBefore = TestExecutionEvent.TEST_EXECUTION)
public void expectToWork() {
...
}
在使用 Spring MockMVC 的 JUnit 测试中,有两种方法可以作为 Spring 安全用户进行身份验证:@WithMockUser
使用提供的凭据创建一个虚拟用户,@WithUserDetails
获取用户名并使用自定义 UserDetailsService
(UserDetailsServiceImpl
)将其解析为正确的自定义 UserDetails
实现。
在我的例子中,UserDetailsService
从数据库加载一个用户。我要使用的用户已插入到测试套件的 @Before
方法中。
但是,我的UserDetailsServiceImpl
没有找到用户。
在我的 @Before
中,我这样插入用户:
User u = new User();
u.setEMail("test@test.de");
u = userRepository.save(u);
并且在 UserDetailsServiceImpl
中:
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = this.userRepository.findOneByEMail(username);
if (user == null)
throw new UsernameNotFoundException(String.format("No user found with username '%s'.", username));
return user;
}
如何将在 @Before
中创建的帐户用于 @WithUserDetails
?
不幸的是,您无法使用 @Before
轻松完成 @WithUserDetails
,因为 Spring @WithUserDetails
注释将在 [之前调用 Spring 安全上下文测试侦听器=22=] setUp
方法与 @Before
.
这里是
@Inject
private EntityManager em;
@Inject
PlatformTransactionManager txManager;
@BeforeTransaction
public void setup() {
new TransactionTemplate(txManager).execute(status -> {
User u = new User();
u.setEMail("test@test.de");
em.save(u);
return null;
});
}
@AfterTransaction
public void cleanup() {
new TransactionTemplate(txManager).execute(status -> {
// Check if the entity is managed by EntityManager.
// If not, make it managed with merge() and remove it.
em.remove(em.contains(u) ? user1 : em.merge(u));
return null;
});
}
@Test
@Transactional
@WithUserDetails(value = "test@test.de", userDetailsServiceBeanName = "loadUserByUsername")
public void test() {
}
您可以使用 @PostConstruct
而不是 @Before
。那对我有用。有人可以证实吗?
使用setupBefore = TEST_EXECUTION
这将有效地导致 @WithUserDetails
在 @Before
和 @BeforeEach
@BeforeEach
public void createUser() {
...
}
@Test
@WithUserDetails(value = "username", setupBefore = TestExecutionEvent.TEST_EXECUTION)
public void expectToWork() {
...
}