spring-boot - 为安全控制器的集成测试设置身份验证
问题描述
我无法为我的休息控制器集成测试设置身份验证。控制器的方法如下所示:
@RestController
@RequestMapping(BASE_URL)
@RequiredArgsConstructor
public class EventController {
public static final String BASE_URL = "/api/event";
@PostMapping
@PreAuthorize("hasRole('USER')")
public void createEvent() {
System.out.println("I am in controller");
}
}
这是我的测试:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class EventControllerTest {
private MockMvc mockMvc;
@Autowired
private WebApplicationContext context;
@BeforeEach
public void setup() {
mockMvc = MockMvcBuilders
.webAppContextSetup(context)
.apply(springSecurity())
.build();
}
@Test
void create() throws Exception {
this.mockMvc.perform(post(EventController.BASE_URL)
.with(authentication(new UsernamePasswordAuthenticationToken(
new MyPrincipal(100, "denis"),
null,
Collections.singletonList(new SimpleGrantedAuthority("USER"))
)))
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType("application/json"));
}
由于状态原因,我的测试总是失败,401
所以我的模拟身份验证不起作用。你能告诉我如何解决吗?谢谢你的建议。
解决方案
测试安全请求的最简单方法是使用@WithMockUser(A_ROLE)
所以你的测试看起来像
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@SpringBootTest
@AutoConfigureMockMvc
class EventControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
@WithMockUser("USER")
void create() throws Exception {
this.mockMvc.perform(post(EventController.BASE_URL)
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType("application/json"));
}
}
一些备注:
- 您的测试需要一个结果,因此请采用您的控制器或测试
@PostMapping
@PreAuthorize("hasRole('ROLE_USER')")
public ResponseEntity<String> createEvent() {
String result = "I am in controller";
System.out.println(result);
return ResponseEntity.ok().body(result);
}
你正在做/测试一个POST
所以确保在你的安全配置中你做http.csrf().disable()....
或在您的测试中提供一个 csrf-token
this.mockMvc.perform(post(EventController.BASE_URL)
.with(SecurityMockMvcRequestPostProcessors.csrf()) // provide a csrf-token
....
'
推荐阅读
- c# - Html.ValidationSummary 总是显示
- javascript - 如何通过javascript将视频添加到html页面
- javascript - Select2 未使用 Jquery 3.3.1 上的 jquery-validate 插件进行验证
- amazon-web-services - 是否有通过 CLI 启用 aws 守卫职责的脚本?
- java - 如何在不读取 Java 中的整个 JSON 文件的情况下仅获取特定键的值?
- angular - VS Code 中的 Angular:是否有任何自动重命名的方法?
- java - Tomcat 9 和 Java 11 上的 Soap Web 服务响应不同
- css - 将 css 应用于直接子元素
- java - File Writer写入方法期间发生java Stream closed异常
- angular - 从角度的url中检索查询参数