spring-security - JUnit5 使用 Spring 安全性测试安全控制器
问题描述
我有一个简单的控制器,只能在安全的上下文中访问。在我的应用程序中,我只将其他 URL 列入白名单,而不是/user
.
在单曲的单元测试中,@GetResponse
我得到了 401 而不是 200 的 Http 状态。我期待这个,因为它是安全的。
当我使用登录用户实际运行应用程序时,我得到一个 200 和一个有效的结果。
如何对请求的行为和任何其他安全控制器路径进行单元测试?
单元测试:
@SpringBootTest
@AutoConfigureMockMvc
class UserControllerTest {
@InjectMocks
UserController userController;
@Autowired
private MockMvc mockMvc;
@Autowired
private ApplicationContext applicationContext;
@Test
void getUserNone() throws Exception {
mockMvc
.perform(MockMvcRequestBuilders.get("/user"))
.andExpect(status().isOk());
}
}
应用程序:
@SpringBootApplication
public class WebApp extends WebSecurityConfigurerAdapter {
public static void main(final String... args) {
SpringApplication.run(WebApp.class, args);
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
http
.authorizeRequests(a -> a
.antMatchers("/error", "/css/**", "/webjars/**").permitAll()
.anyRequest().authenticated()
)
.exceptionHandling(e -> e
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
)
.oauth2Login();
}
}
控制器:
@Controller
public class UserController {
@GetMapping("/user")
public @ResponseBody
Map<String, Object> getUser(@AuthenticationPrincipal final OAuth2User principal) {
if (principal == null) {
return Collections.EMPTY_MAP;
} else {
return Collections.singletonMap("name", principal.getName());
}
}
}
显然,我可以添加/user
到白名单路径,但这对于应用程序的任何安全部分都是不正确的。
解决方案
您可以使用注释@WithMockUser
并@WithAnonymousUser
创建一个Authentication
填充在SecurityContext
. 文档可以在这里找到。
示例代码:
@Test
@WithMockUser("john")
void testAuthorize() throws Exception {
mockMvc
.perform(MockMvcRequestBuilders.get("/user"))
.andExpect(status().isOk());
}
@Test
@WithAnonymousUser
void testUnauthorized() throws Exception {
mockMvc
.perform(MockMvcRequestBuilders.get("/user"))
.andExpect(status().isUnauthorized());
}
推荐阅读
- ffmpeg - 如何使用 ffmpeg 缩放图像并指定每秒所需的帧数?
- ruby-on-rails - 选择年份的空默认值
- javascript - React 原生底部导航栏
- javascript - 禁用提交 btn 时,预填充的表单输入元素不接受第一个输入
- groovy - 您可以将变量传递给 Groovy 的评估(文件文件)吗?
- java - 我可以从 Activity 更新 ViewHolder 变量吗?
- c# - 使用 HtmlAgilityPack 获取 HTML 代码的内容
- c# - 根据实体框架中的特定列获取不同的条目
- python - 如何使用 numba 在内核中分配数组?
- reactjs - 是否可以从代码沙箱本身构建一个反应应用程序?