MockMvc使用模拟会话来绕过安全性

Kie*_*eli 2 java junit spring spring-security spring-boot

我正在一套微服务中开发一个spring-boot微服务.服务端点都使用两个功能进行保护:@PreAuthorize注释和提供额外无状态身份验证的自定义GenericFilterBean.

有些人使用MockMvc首先发布到登录URL,然后从指定的端点获取.这对我来说是个问题,因为登录是由不同的微服务执行的.

我做了不同的尝试而没有完全理解,可以概括为:

  1. 通过其他微服务登录以获取具有cookie集的会话
  2. 模拟会话以使用假cookie
  3. 禁用安全和自定义筛选器

MockMvc不允许调用外部URL来执行登录,因此第一个被排除.模拟会话似乎没有给我一个设置cookie的方法 - 我只在响应对象上看到addCookie.禁用自定义过滤器导致没有任何事情发生(也许我做错了).

在我看来,正确的测试方法是拥有一个有效的模拟会话并允许安全性保持不变.我很难过如何继续.

spring-boot父pom是:spring-cloud-starter-parent - Brixton.M4

如何测试单个微服务并绕过安全性?

小智 5

我前一段时间遇到过类似的问题,花了一些时间才找到答案,不确定这是否能解决您的问题,但我可以设法使用mockMvc使用以下方法进行身份验证

创建一个负责身份验证的类.它可能是这样的

public class Auth {  

    @Autowired
    private WebApplicationContext wac;

    @Autowired
    private FilterChainProxy springSecurityFilter;

    protected MockMvc mockMvc;
    protected MockHttpSession session;

    public void setup() throws Exception{
        this.session = new MockHttpSession();
        this.mockMvc = MockMvcBuilders.webAppContextSetup(wac)
                .addFilters(springSecurityFilter)
                .build();
    }

    protected void setAuthentication(String user, String password, MockHttpSession session){
        Authentication authentication = new UsernamePasswordAuthenticationToken(user, password);
        SecurityContext securityContext = SecurityContextHolder.getContext();
        securityContext.setAuthentication(authentication);

        session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY,securityContext);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在您可以简单地扩展此类并使用方法setAuthenticatio登录并执行测试.例如

public class myTest extends Auth {
     @Test
     public void test{ 
         setAuthentication('user', 'password', session);
         // perform you tests using mockmvc
         // mockMvc.perform(post('url')...

     }

}
Run Code Online (Sandbox Code Playgroud)