我正在使用Spring Framework
和Spring Security
关于测试
对于@Controller
安全的一组测试类,使用.apply(springSecurity()
和@WithUserDetails(value="something")
@Before
public void setUp(){
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.apply(springSecurity())// <---
.build();
}
对于其他的@Controller
的测试类集,没有 安全,因此.apply(springSecurity())
和< / em> @WithUserDetails(value="something")
不使用。
@Before
public void setUp(){
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.build();
}
直到此处@Controller
与和没有安全性的所有工作都正常。
问题出在@Service
,定义@EnableGlobalMethodSecurity
且@Service
方法注释为@PreAuthorize("hasRole('ROLE_ADMIN')")
,所有其他测试@Service
的安全 的类现在失败,但是:
org.springframework.security.authentication.AuthenticationCredentialsNotFoundException:
An Authentication object was not found in the SecurityContext
当然是因为@Test
方法不使用@WithUserDetails(value="something")
因此,实际上.apply(springSecurity())
完成了这项工作,但是通过MockMvcBuilders.webAppContextSetup(webApplicationContext)
但对于服务器端, security 需要
@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;
...
因此MockMvcBuilders.webAppContextSetup(webApplicationContext)
无意义使用。解决这个问题的最佳方法是什么?
答案 0 :(得分:2)
您也可以使用@WithUserDetails
和@WithMockUser
来测试方法的安全性。
为了测试有关方法安全性的测试,您需要在用于加载@EnableGlobalMethodSecurity
的组件类中包括用ApplicationContext
注释的类。
例如,如果配置类SecurityConfig
用EnableGlobalMethodSecurity
注释
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig { }
服务MessageService
具有使用@PreAuthorize
的方法。
@Service
public class MessageService {
public String getHelloMessage() {
return "Hello!";
}
@PreAuthorize("hasRole('ADMIN')")
public String getGoodbyeMessage() {
return "Goodbye!";
}
}
然后,您需要在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!");
}
}