为安全控制器的集成测试设置身份验证
Posted
技术标签:
【中文标题】为安全控制器的集成测试设置身份验证【英文标题】:Set authentication for Integration test of secured Controller 【发布时间】:2020-05-23 11:55:45 【问题描述】:我无法为我的 REST 控制器集成测试设置身份验证。 Controller的方法是这样的:
@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
状态,我的测试总是失败,所以我的模拟身份验证不起作用。你能告诉我如何解决吗?谢谢你的建议。
【问题讨论】:
身份验证如何在您的应用程序中工作? @SupunWijerathne 有基于 jwt 令牌的身份验证。 【参考方案1】:测试安全请求的最简单方法是使用@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
....
'
【讨论】:
这总是给我 401 未授权 @DenisStephanov 改进了我的答案 same :/ 我们用于认证 oauth 令牌,这会导致这个问题吗? @DenisStephanov 这确实可以有所作为...不是我的领域,也许这个oauth-api-testing-with-spring-mvc 可以提供帮助以上是关于为安全控制器的集成测试设置身份验证的主要内容,如果未能解决你的问题,请参考以下文章
Symfony2 - 将安全访问控制设置为只允许匿名身份验证