Spring Security(三十六):12. Spring MVC Test Integration
Spring Security provides comprehensive integration with Spring MVC Test
12.1 Setting Up MockMvc and Spring Security
In order to use Spring Security with Spring MVC Test it is necessary to add the Spring Security FilterChainProxy as a Filter. It is also necessary to add Spring Security’s TestSecurityContextHolderPostProcessor to support Running as a User in Spring MVC Test with Annotations. This can be done using Spring Security’s SecurityMockMvcConfigurers.springSecurity(). For example:
Spring Security’s testing support requires spring-test-4.1.3.RELEASE or greater.
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*; @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@WebAppConfiguration
public class CsrfShowcaseTests { @Autowired
private WebApplicationContext context; private MockMvc mvc; @Before
public void setup() {
mvc = MockMvcBuilders
.webAppContextSetup(context)
.apply(springSecurity()) 1
.build();
} ...
1.SecurityMockMvcConfigurers.springSecurity() will perform all of the initial setup we need to integrate Spring Security with Spring MVC Test
12.2 SecurityMockMvcRequestPostProcessors
Spring MVC Test provides a convenient interface called a RequestPostProcessor that can be used to modify a request. Spring Security provides a number of RequestPostProcessor implementations that make testing easier. In order to use Spring Security’s RequestPostProcessor implementations ensure the following static import is used:
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*;
12.2.1 Testing with CSRF Protection
When testing any non-safe HTTP methods and using Spring Security’s CSRF protection, you must be sure to include a valid CSRF Token in the request. To specify a valid CSRF token as a request parameter using the following:
mvc.perform(post("/").with(csrf()))
If you like you can include CSRF token in the header instead:
mvc.perform(post("/").with(csrf().asHeader()))
You can also test providing an invalid CSRF token using the following:
mvc.perform(post("/").with(csrf().useInvalidToken()))
12.2.2 Running a Test as a User in Spring MVC Test
It is often desirable to run tests as a specific user. There are two simple ways of populating the user:
- Running as a User in Spring MVC Test with RequestPostProcessor
- 使用RequestPostProcessor在Spring MVC Test中作为用户运行
- Running as a User in Spring MVC Test with Annotations
- 在带有注释的Spring MVC测试中作为用户运行
12.2.3 Running as a User in Spring MVC Test with RequestPostProcessor
There are a number of options available to associate a user to the current HttpServletRequest. For example, the following will run as a user (which does not need to exist) with the username "user", the password "password", and the role "ROLE_USER":
The support works by associating the user to the HttpServletRequest. To associate the request to the SecurityContextHolder you need to ensure that the SecurityContextPersistenceFilter is associated with the MockMvc instance. A few ways to do this are:
- Invoking apply(springSecurity())
- Adding Spring Security’s
FilterChainProxytoMockMvc - Manually adding
SecurityContextPersistenceFilterto theMockMvcinstance may make sense when usingMockMvcBuilders.standaloneSetup - 使用MockMvcBuilders.standaloneSetup时,手动将SecurityContextPersistenceFilter添加到MockMvc实例可能有意义
mvc.perform(get("/").with(user("user")))
You can easily make customizations. For example, the following will run as a user (which does not need to exist) with the username "admin", the password "pass", and the roles "ROLE_USER" and "ROLE_ADMIN".
mvc.perform(get("/admin").with(user("admin").password("pass").roles("USER","ADMIN")))
If you have a custom UserDetails that you would like to use, you can easily specify that as well. For example, the following will use the specified UserDetails (which does not need to exist) to run with a UsernamePasswordAuthenticationToken that has a principal of the specified UserDetails:
mvc.perform(get("/").with(anonymous()))
This is especially useful if you are running with a default user and wish to execute a few requests as an anonymous user.
Authentication (which does not need to exist) you can do so using the following:mvc.perform(get("/").with(authentication(authentication)))
You can even customize the SecurityContext using the following:
mvc.perform(get("/").with(securityContext(securityContext)))
We can also ensure to run as a specific user for every request by using MockMvcBuilders's default request. For example, the following will run as a user (which does not need to exist) with the username "admin", the password "password", and the role "ROLE_ADMIN":
mvc = MockMvcBuilders
.webAppContextSetup(context)
.defaultRequest(get("/").with(user("user").roles("ADMIN")))
.apply(springSecurity())
.build();
If you find you are using the same user in many of your tests, it is recommended to move the user to a method. For example, you can specify the following in your own class named CustomSecurityMockMvcRequestPostProcessors:
public static RequestPostProcessor rob() {
return user("rob").roles("ADMIN");
}
Now you can perform a static import on SecurityMockMvcRequestPostProcessors and use that within your tests:
import static sample.CustomSecurityMockMvcRequestPostProcessors.*; ... mvc
.perform(get("/").with(rob()))
Running as a User in Spring MVC Test with Annotations
RequestPostProcessor to create your user, you can use annotations described in Chapter 11, Testing Method Security. For example, the following will run the test with the user with username "user", password "password", and role "ROLE_USER":@Test
@WithMockUser
public void requestProtectedUrlWithUser() throws Exception {
mvc
.perform(get("/"))
...
}
Alternatively, the following will run the test with the user with username "user", password "password", and role "ROLE_ADMIN":
@Test
@WithMockUser(roles="ADMIN")
public void requestProtectedUrlWithUser() throws Exception {
mvc
.perform(get("/"))
...
}
12.2.4 Testing HTTP Basic Authentication
While it has always been possible to authenticate with HTTP Basic, it was a bit tedious to remember the header name, format, and encode the values. Now this can be done using Spring Security’s httpBasic RequestPostProcessor. For example, the snippet below:
mvc.perform(get("/").with(httpBasic("user","password")))
will attempt to use HTTP Basic to authenticate a user with the username "user" and the password "password" by ensuring the following header is populated on the HTTP Request:
Authorization: Basic dXNlcjpwYXNzd29yZA==
12.3 SecurityMockMvcRequestBuilders
Spring MVC Test also provides a RequestBuilder interface that can be used to create the MockHttpServletRequest used in your test. Spring Security provides a few RequestBuilder implementations that can be used to make testing easier. In order to use Spring Security’s RequestBuilder implementations ensure the following static import is used:
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.*;
12.3.1 Testing Form Based Authentication
You can easily create a request to test a form based authentication using Spring Security’s testing support. For example, the following will submit a POST to "/login" with the username "user", the password "password", and a valid CSRF token:
mvc.perform(formLogin())
It is easy to customize the request. For example, the following will submit a POST to "/auth" with the username "admin", the password "pass", and a valid CSRF token:
mvc.perform(formLogin("/auth").user("admin").password("pass"))
We can also customize the parameters names that the username and password are included on. For example, this is the above request modified to include the username on the HTTP parameter "u" and the password on the HTTP parameter "p".
mvc.perform(formLogin("/auth").user("u","admin").password("p","pass"))
12.3.2 Testing Logout
While fairly trivial using standard Spring MVC Test, you can use Spring Security’s testing support to make testing log out easier. For example, the following will submit a POST to "/logout" with a valid CSRF token:
mvc.perform(logout())
You can also customize the URL to post to. For example, the snippet below will submit a POST to "/signout" with a valid CSRF token:
mvc.perform(logout("/signout"))
12.4 SecurityMockMvcResultMatchers
At times it is desirable to make various security related assertions about a request. To accommodate this need, Spring Security Test support implements Spring MVC Test’s ResultMatcher interface. In order to use Spring Security’s ResultMatcher implementations ensure the following static import is used:
mvc
.perform(formLogin().password("invalid"))
.andExpect(unauthenticated());
12.4.2 Authenticated Assertion
It is often times that we must assert that an authenticated user exists. For example, we may want to verify that we authenticated successfully. We could verify that a form based login was successful with the following snippet of code:
mvc
.perform(formLogin())
.andExpect(authenticated());
If we wanted to assert the roles of the user, we could refine our previous code as shown below:
mvc
.perform(formLogin().user("admin"))
.andExpect(authenticated().withRoles("USER","ADMIN"));
Alternatively, we could verify the username:
mvc
.perform(formLogin().user("admin"))
.andExpect(authenticated().withUsername("admin"));
We can also combine the assertions:
mvc
.perform(formLogin().user("admin").roles("USER","ADMIN"))
.andExpect(authenticated().withUsername("admin"));
Spring Security(三十六):12. Spring MVC Test Integration的更多相关文章
- Spring Security(十六):5.7 Multiple HttpSecurity
We can configure multiple HttpSecurity instances just as we can have multiple <http> blocks. T ...
- spring boot / cloud (十六) 分布式ID生成服务
spring boot / cloud (十六) 分布式ID生成服务 在几乎所有的分布式系统或者采用了分库/分表设计的系统中,几乎都会需要生成数据的唯一标识ID的需求, 常规做法,是使用数据库中的自动 ...
- Gradle 1.12用户指南翻译——第三十六章. Sonar Runner 插件
本文由CSDN博客万一博主翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...
- Spring Security(十二):5. Java Configuration
General support for Java Configuration was added to Spring Framework in Spring 3.1. Since Spring Sec ...
- Spring Security(三) —— 核心配置解读
摘要: 原创出处 https://www.cnkirito.moe/spring-security-3/ 「老徐」欢迎转载,保留摘要,谢谢! 3 核心配置解读 上一篇文章<Spring Secu ...
- Spring Security(十):3. What’s New in Spring Security 4.2 (新功能)
Among other things, Spring Security 4.2 brings early support for Spring Framework 5. You can find th ...
- 程序员编程艺术第三十六~三十七章、搜索智能提示suggestion,附近点搜索
第三十六~三十七章.搜索智能提示suggestion,附近地点搜索 作者:July.致谢:caopengcs.胡果果.时间:二零一三年九月七日. 题记 写博的近三年,整理了太多太多的笔试面试题,如微软 ...
- centos shell脚本编程2 if 判断 case判断 shell脚本中的循环 for while shell中的函数 break continue test 命令 第三十六节课
centos shell脚本编程2 if 判断 case判断 shell脚本中的循环 for while shell中的函数 break continue test 命令 ...
- Spring Boot 2.X(六):Spring Boot 集成Redis
Redis 简介 什么是 Redis Redis 是目前使用的非常广泛的免费开源内存数据库,是一个高性能的 key-value 数据库. Redis 与其他 key-value 缓存(如 Memcac ...
随机推荐
- Spring Boot2.0:使用Docker部署Spring Boot
一.Spring Boot项目添加 Docker 支持1.在pom.xml中添加 Docker 构建插件 <plugins> <!-- Docker maven plugin --& ...
- Linux基础知识第四讲,文件内容命令
目录 一丶常用命令 1.cat命令演示以及常用选项 2.grep 搜索命令的使用 3.echo 以及 重定向的使用 4.管道概念 一丶常用命令 序号 命令 对应英文 作用 01 cat 文件名 con ...
- React组件方法中为什么要绑定this
如果你尝试使用过React进行前端开发,一定见过下面这样的代码: //假想定义一个ToggleButton开关组件 class ToggleButton extends React.Component ...
- [Go] golang互斥锁mutex
1.互斥锁用于在代码上创建一个临界区,保证同一时间只有一个goroutine可以执行这个临界区代码2.Lock()和Unlock()定义临界区 package main import ( " ...
- C++系列总结——mutable关键字
介绍 mutable的中文意思是易变的,是C++的一个关键字.它的作用就是允许修改被const修饰的对象的成员变量. 常用场景 什么情况下我们会使用到mutable? 一般我们会用const修饰get ...
- 面试题之(vue生命周期)
在面试的时候,vue生命周期被考察的很频繁. 什么是vue生命周期呢? Vue实例有一个完整的生命周期,也就是从开始创建.初始化数据.编译模板.挂载Dom.渲染→更新→渲染.卸载等一系列过程,我们称这 ...
- 小程序多端框架全面测评:chameleon、Taro、uni-app、mpvue、WePY
摘要: 微信小程序开发技巧. 作者:coldsnap 原文:小程序多端框架全面测评 Fundebug经授权转载,版权归原作者所有. 最近前端届多端框架频出,相信很多有代码多端运行需求的开发者都会产生一 ...
- 快速傅里叶变换(FFT)详解
本文只讨论FFT在信息学奥赛中的应用 文中内容均为个人理解,如有错误请指出,不胜感激 前言 先解释几个比较容易混淆的缩写吧 DFT:离散傅里叶变换—>$O(n^2)$计算多项式乘法 FFT:快速 ...
- 惊喜,重磅福利!免费开源ERP-企业信息化金矿
Odoo,以前叫OpenERP,是比利时Odoo S.A.公司开发的一个企业应用软件套件,开源套件包括一个企业应用快速开发平台,以及几千个Odoo及第三方开发的企业应用模块.Odoo适用于各种规模的企 ...
- Android studio设置文件头,定制代码注释
一.说明 在下载或者看别人的代码我们常会看见,每一个文件的上方有个所属者的备注.如果要是一个一个备注那就累死了. 二.设置方法 File >>> Setting >>&g ...