java - 简单地测试 Spring Boot 安全性

标签 java spring security testing spring-boot

我正在努力测试受 Spring Security 保护的 URL 的访问控制。

配置如下:

    http
            .authorizeRequests()
            .antMatchers("/api/user/**", "/user").authenticated()
            .antMatchers("/api/admin/**", "/templates/admin/**", "/admin/**").hasAuthority("ADMIN")
            .anyRequest().permitAll();

而测试类看起来是这样的:

package com.kubukoz.myapp;

import com.kubukoz.myapp.config.WebSecurityConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.security.web.FilterChainProxy;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import javax.transaction.Transactional;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;


@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {MyApplication.class, WebSecurityConfig.class})
@WebAppConfiguration
@TransactionConfiguration(defaultRollback = true)
@Transactional(rollbackOn = Exception.class)
public class MyApplicationTests {

    @Autowired
    private WebApplicationContext context;
    private MockMvc mockMvc;
    @Autowired
    private FilterChainProxy filterChainProxy;

    @Before
    public void setUp() {
        mockMvc = MockMvcBuilders.webAppContextSetup(context)
                .dispatchOptions(true)
                .addFilters(filterChainProxy)
                .build();
    }

    @Test
    public void testAnonymous() throws Exception {
        mockMvc.perform(get("/api/user/account")).andExpect(status().is3xxRedirection());
    }

    @Test
    public void testUserAccessForAccount() throws Exception{
        mockMvc.perform(get("/api/user/account")).andExpect(status().isOk());
    }
}

让最后两个测试通过的最简单方法是什么? @WithMockUser 不起作用。

最佳答案

您不应该直接添加 FilterChainProxy。相反,您应该按照 the reference 的指示应用 SecurityMockMvcConfigurers.springSecurity() .下面是一个例子:

mockMvc = MockMvcBuilders
            .webAppContextSetup(context)
            .apply(springSecurity())
            .build();

这样的结果是:

  • FilterChainProxy 被添加为 FilterMockMvc(就像你做的那样)
  • 添加了TestSecurityContextHolderPostProcessor

为什么需要TestSecurityContextHolderPostProcessor?原因是我们需要将当前用户从测试方法传递给创建的 MockHttpServletRequest。这是必要的,因为 Spring Security 的 SecurityContextRepositoryFilter 将覆盖 SecurityContextHolder 上的任何值,使其成为当前 SecurityContextRepository 找到的值(即 SecurityContext HttpSession)。

更新

记住方法名称中包含角色的任何内容都会自动将“ROLE_”作为传入字符串的前缀。

根据您的评论,问题是您需要更新配置以使用 hasRole 而不是 hasAuthority(因为您的注释使用角色):

.authorizeRequests()
            .antMatchers("/api/user/**", "/user").authenticated()
            .antMatchers("/api/admin/**", "/templates/admin/**", "/admin/**").hasRole("ADMIN")
            .anyRequest().permitAll();

或者

您在 Spring Security 4.0.2+ 中可以使用:

@WithMockUser(authorities="ADMIN")

关于java - 简单地测试 Spring Boot 安全性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31812054/

相关文章:

java - Cookie 未通过客户端浏览器中的 httpserveletrresponse 中的 Spring Rest 重定向 api 在浏览器中设置

security - 具有外部用户访问控制的 MediaWiki 文档

security - 检查 TLS 实现中的错误

java - ActiveMQ,代理接收要发送的消息的时间戳

java - 重置 spring url。提交表单两次后附加 URL

java - hazelcast map 放置操作不起作用

spring - Spring Boot Gradle-无法解析所有工件以进行配置

iOS:CCCrypt() kCCOptionECBMode 和 kCCModeCBC 哪个更安全

java - 如何?在 Java 中绘制自定义复合对象

java - 是否可以在单个 bean 声明中声明多个微米绑定(bind)器