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 ...
随机推荐
- SpringBoot使用@Cacheable实现最简单的Redis缓存
前言 之前我们使用过RedisTemplate来实现redis缓存,然后使用工具类来实现操作redis的存储.这样的方式好处是很自由,但是还不是最简单的处理方式.对于一些简单的应用来说,其实redis ...
- 【Java基础】【08面向对象_继承&方法&final】
08.01_面向对象(代码块的概述和分类)(了解)(面试的时候会问,开发不用或者很少用) A:代码块概述 在Java中,使用{}括起来的代码被称为代码块. B:代码块分类 根据其位置和声明的不同,可以 ...
- leetcode — minimum-depth-of-binary-tree
/** * Source : https://oj.leetcode.com/problems/minimum-depth-of-binary-tree/ * * * Given a binary t ...
- spring原理案例-基本项目搭建 02 spring jar包详解 spring jar包的用途
Spring4 Jar包详解 SpringJava Spring AOP: Spring的面向切面编程,提供AOP(面向切面编程)的实现 Spring Aspects: Spring提供的对Aspec ...
- CentOS 7 镜像文件各个版本区别
CentOS ISO 镜像文件的功能 引导安装 CentOS ISO 镜像文件包含有安装程序,官方称其为 Anaconda,用来引导安装 CentOS 提供 CentOS 的安装文件 镜像文件不一定包 ...
- 常用的String原型
对于常用的字符串原型的举例 在字符串末尾追加字符串 String.prototype.append = function (str) { return this.concat(str);} 删除指定索 ...
- java-HashMap默认机制
HashMap:键值对(key-value): 通过对象来对对象进行索引,用来索引的对象叫做key,其对应的对象叫做value. 默认是1:1关系: 存在则覆盖,当key已经存在,则利用新的value ...
- 纯CSS实现点击事件展现隐藏div菜单列表/元素切换
在写移动端导航的时候经常用到点击按钮出现/隐藏导航条的情况,最常见的方法当然还是前端框架直接调用,省心省力,不易出错:当然还有使用纯JS实现的小代码段.我这里整理了纯CSS实现方式,给需要的人和给自己 ...
- mathjs,math.js解决js运算精度问题
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- HTML的概念和三大基石以及标准文档结构
HTML的概念: 概念: HTML:超文本标记语言 作用: 需要将java在后台根据用户请求处理的请求结果在浏览器中显示给用户. 在浏览器中数据需要使用友好的格式展示给用户. HTML是告诉浏 ...