spring-security 如何在https spring安全单元测试中避免302响应?

e37o9pze  于 2022-11-11  发布在  Spring
关注(0)|答案(4)|浏览(190)

我已经有了java Spring Security应用程序(用jhipster构建),我正在尝试添加一些单元测试,这些测试基于当前已验证用户的逻辑。
为此,我配置了MockMvc对象,以使用Web应用程序上下文和Spring安全性,如下所示:

@Test
@Transactional
public void getAllContacts() throws Exception {
    restContactMockMvc = MockMvcBuilders
        .webAppContextSetup(context)
        .apply(springSecurity())
        .build();
    restContactMockMvc.perform(get("/api/contacts")).andExpect(status().isOk());
}

问题是我还将应用程序配置为需要HTTPS,每当我运行此单元测试时,我都会得到一个302重定向响应,因为它似乎试图发送HTTP请求而不是HTTPS。
我在SecurityConfiguration.configure(HttpSecurity http)中执行HTTPS的方式是使用以下行:

if (env.acceptsProfiles("!dev"))http.requiresChannel().anyRequest().requiresSecure();

所以,我的问题是如何让我的单元测试正确运行?可能是通过发送一个模拟的HTTPS请求,或者在运行单元测试的情况下禁用HTTPS?

zbq4xfa0

zbq4xfa01#

使用Springs MockMvc工具,您还可以指定要使用secure(true)方法发送模拟HTTPS请求,如下所示:

restContactMockMvc.perform( get("/api/contacts").secure( true ) ).andExpect( status().isOk() )
deikduxw

deikduxw2#

我正在用我已经开始使用的修复程序来回答我自己的问题,希望这能帮助其他人。我仍然对其他更好的解决方案持开放态度。
SecurityConfiguration.configure(HttpSecurity http)方法中,我修改了if语句,以便在运行integrationTest时跳过它来强制https:

if (env.acceptsProfiles("!dev") && !((StandardEnvironment) env).getPropertySources().contains("integrationTest")) {
        http.requiresChannel().anyRequest().requiresSecure();
}
guykilcj

guykilcj3#

除了正确的答案@rhinds之外,您还可以将以下代码添加到@Before方法中,以使所有调用在默认情况下都是安全的:

import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.testSecurityContext;

public class YourTestClass {
    @Autowired
    private Filter springSecurityFilterChain;
    @Autowired
    private SecurityTestController securityTestController;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        mockMvc = standaloneSetup(securityTestController)
            .addFilters(springSecurityFilterChain)
            .defaultRequest(get("/").secure(true).with(testSecurityContext()))
            .build();
    }

    // Your Tests Here

    @Test
    public void httpsRedirect() throws Exception {
        mockMvc.perform(get("/").secure(false))
            .andExpect(status().isFound())
            .andExpect(result -> StringUtils.isNotEmpty(result.getResponse().getHeader("Location")))
            .andExpect(result -> result.getResponse().getHeader("Location").startsWith("https://"));
    }
}
gk7wooem

gk7wooem4#

如果配置不正确,Spring Security会将响应状态更改为“302 FOUND”。请仔细检查您的安全配置。

@Bean
@Throws(Exception::class)
fun authTokenFilterBean(): CustomAuthTokenFilter {
    val authTokenFilter = CustomAuthTokenFilter()
    // if you don't have these lines, add them:
    authTokenFilter.setAuthenticationSuccessHandler(MyAuthSuccessHandler())
    authTokenFilter.setAuthenticationFailureHandler(MyAuthFailureHandler())
    return authTokenFilter
}

其中

  • CustomAuthTokenFilterAbstractAuthenticationProcessingFilter的自定义实现;
  • MyAuthSuccessHandlerMyAuthFailureHandler是您提供处理程序它们可以为空,也可以包含您自定义逻辑

相关问题