Man*_*dan 3 spring spring-security
我正在与Spring Framework和Spring Security
关于测试
@Controller 对于具有 安全性的一组测试类,.apply(springSecurity()使用@WithUserDetails(value="something")
@Before
public void setUp(){
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.apply(springSecurity())// <---
.build();
}
Run Code Online (Sandbox Code Playgroud)
对于没有安全性的其他测试类集,因此不使用和。@Controller .apply(springSecurity()) @WithUserDetails(value="something")
@Before
public void setUp(){
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.build();
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,所有关于@Controller 有或没有安全的情况都可以正常工作。
问题在于@Service,当@EnableGlobalMethodSecurity定义并且@Service方法用 注释时@PreAuthorize("hasRole('ROLE_ADMIN')"),不需要安全性的所有其他测试类现在都会失败:@Service
org.springframework.security.authentication.AuthenticationCredentialsNotFoundException:
An Authentication object was not found in the SecurityContext
Run Code Online (Sandbox Code Playgroud)
当然是因为@Test方法不使用@WithUserDetails(value="something")
因此,实际上.apply(springSecurity())可以完成这项工作,但它对于Web环境来说是通过MockMvcBuilders.webAppContextSetup(webApplicationContext)
但对于不需要安全性的服务器端,我有:
@Transactional
@RunWith(Parameterized.class)
@ContextConfiguration(classes={RootApplicationContext.class})
@ActiveProfiles(resolver=TestActiveProfilesResolver.class)
@TestExecutionListeners(listeners={LoggingTestExecutionListener.class}, mergeMode=MergeMode.MERGE_WITH_DEFAULTS)
public class PersonaServiceImplTest {
private static final Logger logger = LoggerFactory.getLogger(PersonaServiceImplTest.class.getSimpleName());
@ClassRule
public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
@Rule
public final SpringMethodRule springMethodRule = new SpringMethodRule();
@Autowired
private Environment environment;
...
Run Code Online (Sandbox Code Playgroud)
因此MockMvcBuilders.webAppContextSetup(webApplicationContext)没有使用意义。解决这个问题的最佳方法是什么?
您也可以使用@WithUserDetails和来测试方法的安全性。
为了测试方法安全性,您需要在用于加载.@WithMockUser@EnableGlobalMethodSecurityApplicationContext
例如,如果配置类SecurityConfig注释为EnableGlobalMethodSecurity
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig { }
Run Code Online (Sandbox Code Playgroud)
并且该服务MessageService有一个使用的方法@PreAuthorize。
@Service
public class MessageService {
public String getHelloMessage() {
return "Hello!";
}
@PreAuthorize("hasRole('ADMIN')")
public String getGoodbyeMessage() {
return "Goodbye!";
}
}
Run Code Online (Sandbox Code Playgroud)
然后您需要将这两个类包含在 中,MessageServiceTest并且可以使用安全测试注释。
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {SecurityConfig.class, MessageService.class})
public class MessageServiceTest {
@Autowired
MessageService messageService;
@Test
public void helloMessageReturnsHello() {
assertThat(messageService.getHelloMessage()).isEqualTo("Hello!");
}
@Test(expected = AuthenticationCredentialsNotFoundException.class)
public void goodbyeMessageWithoutUserThrowsException() {
messageService.getGoodbyeMessage();
}
@WithMockUser(roles = "ADMIN")
@Test
public void goodbyeMessageWithAdminReturnsGoodbye() {
assertThat(messageService.getGoodbyeMessage()).isEqualTo("Goodbye!");
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1392 次 |
| 最近记录: |