簡體   English   中英

簡單地測試Spring Boot Security

[英]Testing Spring Boot Security simply

我正在努力測試受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。 相反,您應該應用SecurityMockMvcConfigurers.springSecurity()引用所示 下面是一個例子:

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

結果是:

  • FilterChainProxy作為Filter添加到MockMvc (就像你做的那樣)
  • 添加了TestSecurityContextHolderPostProcessor

為什么需要TestSecurityContextHolderPostProcessor 原因是我們需要將當前用戶從測試方法傳遞到創建的MockHttpServletRequest 這是必要的,因為Spring Security的SecurityContextRepositoryFilter將覆蓋任何值SecurityContextHolder是當前發現的價值SecurityContextRepository (即SecurityContextHttpSession )。

更新

請記住,方法名稱中包含role的任何內容都會自動將“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")

好吧,想通了。

mockMvc.perform(get("/api/user/account")
      .with(user("user")))
      .andExpect(status().isOk());

它現在有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM