12. Spring MVC Test Integration(Spring MVC测试集成)

Spring Security提供了与Spring MVC测试的全面集成。

12.1 Setting Up MockMvc and Spring Security(设置MockMvc和Spring安全性)

Spring MVC Test提供了一个方便的接口,称为RequestPostProcessor(请求后处理器),可以用来修改请求。Spring Security提供了许多RequestPostProcessor实现,使得测试更加容易。为了使用Spring Security的RequestPostProcessor实现,请确保使用以下静态导入:

importstaticorg.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*;

12.2.1 Testing with CSRF Protection

当测试任何不安全的HTTP方法并使用Spring Security的CSRF保护时,您必须确保在请求中包含有效的CSRF令牌。使用以下命令将有效的CSRF令牌指定为请求参数:

mvc.perform(post("/").with(csrf()))

1、如果您愿意,可以在标题中包含CSRF令牌:

mvc.perform(post("/").with(csrf().asHeader()))

2、您还可以使用以下方法测试提供无效的CSRF令牌:

mvc.perform(post("/").with(csrf().useInvalidToken()))

12.2.2 Running a Test as a User in Spring MVC Test  在Spring MVC测试中以User运行测试

通常希望以特定用户的身份运行测试。有两种简单的方式来填充用户:见12.2.3

12.2.3 Running as a User in Spring MVC Test with RequestPostProcessor

在带有请求后处理器(RequestPostProcessor)的Spring MVC测试中以User身份运行。

有许多选项可以将用户与当前的HttpServletRequest相关联。例如,以下将作为用户名为“user”、密码为“password”、角色为“ROLE_USER”的用户(不需要存在)运行:

mvc.perform(get("/").with(user("user")))

 

支持通过将用户与HttpServletRequest相关联来工作。要将请求与安全上下文持有者(SecurityContextHolder )相关联,您需要确保安全上下文持久性过滤器(SecurityContextPersistenceFilter )与MockMvc实例相关联。有几种方法可以做到这一点:

    调用应用程序(springSecurity())

    将Spring Security的FilterChainProxy添加到MockMvc

    使用MockMvcbuilders . standalone setup时,向MockMVc实例手动添加securityContextPersistenceFilter可能有意义

 

1、您可以轻松进行自定义。例如,以下将作为用户名为“admin”、密码为“pass”、角色为“ROLE_USER”和“ROLE_ADMIN”的用户(不需要存在)运行。

mvc.perform(get("/admin").with(user("admin").password("pass").roles("USER","ADMIN")))

2、如果您有一个想要使用的自定义用户详细信息,您也可以轻松地指定它。例如,以下将使用指定的用户详细信息(不需要存在)来运行具有指定用户详细信息主体的用户名密码身份验证令牌(UsernamePasswordAuthenticationToken ):

mvc.perform(get("/").with(user(userDetails)))

3、您可以使用以下方式作为匿名用户运行:

mvc.perform(get("/").with(anonymous()))

如果您使用默认用户运行,并且希望以匿名用户身份执行一些请求,这一点尤其有用。

4、如果您想要自定义身份验证(不需要存在),可以使用以下方法:

mvc.perform(get("/").with(authentication(authentication)))

5、您甚至可以使用以下方式自定义安全性上下文:

mvc.perform(get("/").with(securityContext(securityContext)))

6、通过使用MockMvcBuilders的默认请求,我们还可以确保作为每个请求的特定用户运行。例如,以下将作为用户名为“admin”、密码为“password”、角色为“ROLE_ADMIN”的用户(不需要存在)运行:

mvc = MockMvcBuilders.webAppContextSetup(context).

            defaultRequest(get("/").

            with(user("user").

            roles("ADMIN"))).

            apply(springSecurity()).

            build();

7、如果您发现您在许多测试中使用同一个用户,建议您将该用户移至某个方法。例如,您可以在自己的名为customsecuritymockmvCrequestPostprocessors的类中指定以下内容:

publicstaticRequestPostProcessor rob() {returnuser("rob").roles("ADMIN");}

现在,您可以在securitymockmvrequestPostprocessors上执行静态导入,并在测试中使用它:

importstaticsample.CustomSecurityMockMvcRequestPostProcessors.*;...

mvc.perform(get("/").with(rob()))

 

Running as a User in Spring MVC Test with Annotations(通过注释测试springMVC)

作为使用请求后处理器创建用户的替代方法,您可以使用第11章“测试方法安全性”中描述的注释。例如,下面将使用用户名为“user”、密码为“password”、角色为“ROLE_USER”的用户运行测试:

 


 

或者,下面将使用用户名为“user”、密码为“password”、角色为“ROLE_ADMIN”的用户运行测试:

 


 

12.2.4 Testing HTTP Basic Authentication(测试HTTP基本身份验证)

虽然一直以来都有可能通过HTTP Basic进行身份验证,但是记住标头名称、格式和编码值有点乏味。现在,这可以使用Spring Security的httpBasic RequestPostProcessor来完成。例如,下面的代码片段:

mvc.perform(get("/").with(httpBasic("user","password")))

将通过确保在HTTP请求中填充以下标头,尝试使用HTTP Basic验证用户名为“user”且密码为“password”的用户:

Authorization: Basic dXNlcjpwYXNzd29yZA==

12.3 Security Mock Mvc Request Builders(安全模拟Mvc请求生成器)

Spring MVC测试还提供了一个RequestBuilder接口,可以用来创建测试中使用的MockHttpServletRequest。Spring Security提供了一些RequestBuilder实现,可以用来简化测试。为了使用Spring Security的RequestBuilder实现,请确保使用以下静态导入:

importstaticorg.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.*;

12.3.1 Testing Form Based Authentication(基于测试表单的身份验证)

使用Spring Security的测试支持,您可以轻松地创建一个基于表单的身份验证的测试请求。例如,以下用户将使用用户名“user”、密码“password”和有效的CSRF令牌提交“POST to”/“log in”:

mvc.perform(formLogin())

定制请求很容易。例如,下面将提交一个POST到“/auth”,用户名为“admin”,密码为“pass”,有效的CSRF令牌:

mvc.perform(formLogin("/auth").user("admin").password("pass"))

我们还可以自定义用户名和密码所包含的参数名称。例如,这是上面修改过的请求,在HTTP参数“u”中包含用户名,在HTTP参数“p”中包含密码。

mvc.perform(formLogin("/auth").user("u","admin").password("p","pass"))

12.3.2 Testing Logout(测试登出)

虽然使用标准的Spring MVC测试相当简单,但是您可以使用Spring Security的测试支持来使测试注销更加容易。例如,下面将使用有效的CSRF令牌向“/logout”提交post请求:

mvc.perform(logout())

您还可以自定义要请求的URL路径。例如,下面的代码片段将使用有效的CSRF令牌向“/signout”提交一个POST:

mvc.perform(logout("/signout"))

12.4 SecurityMockMvcResultMatchers(安全模拟Mvc结果匹配器)

有时需要对请求做出各种与安全相关的断言。为了适应这种需求,Spring安全测试支持实现了Spring MVC测试的结果匹配器接口。为了使用Spring Security的ResultMatcher实现,请确保使用以下静态导入:

importstaticorg.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.*;

12.4.1 Unauthenticated Assertion(未经验证的断言)

有时,断言没有经过身份验证的用户与MockMvc调用的结果相关联可能是有价值的。例如,您可能想要测试提交无效的用户名和密码,并验证没有用户经过身份验证。利用Spring Security的测试支持,您可以很容易地做到这一点,方法如下:

mvc.perform(formLogin().password("invalid")).andExpect(unauthenticated());

12.4.2 Authenticated Assertion(认证断言)

通常情况下,我们必须断言已经过身份验证的用户存在。例如,我们可能想要验证我们是否成功通过了身份验证。我们可以通过以下代码片段来验证基于表单的登录是否成功:

mvc

.perform(formLogin())

.andExpect(authenticated());

如果我们想要断言用户的角色,我们可以细化我们之前的代码,如下所示:

mvc.perform(formLogin().user("admin")).andExpect(authenticated().withRoles("USER","ADMIN"));

或者,我们可以验证用户名:

mvc.perform(formLogin().user("admin")).andExpect(authenticated().withUsername("admin"));

我们还可以将这些断言结合起来:

mvc.perform(formLogin().user("admin").roles("USER","ADMIN")).andExpect(authenticated().withUsername("admin"));

 

posted @ 2020-08-16 17:12  节日快乐  阅读(342)  评论(0编辑  收藏  举报