java - 使用 Spring Security 进行集成测试

标签 java spring-mvc spring-security integration-testing

我需要向 API 发送一个 get 请求,但尽管放置了 administrator annotation get error @WithMockUser(roles="ADMINISTRADOR")
如何发送请求?

接口(interface)

@RequestMapping(value = "/{id}", method = RequestMethod.GET)
@PostAuthorize("returnObject.instancia == principal.instancia.instancia")
public Validacao retrieve(@PathVariable("id") String id) {
    return validacaoService.retrieve(id);
}

测试

@Test
@WithMockUser(roles = "ADMINISTRADOR")
public void testCRetrieve() throws Exception {
        this.mockMvc
                .perform(get("/api/validacao/" + id).with(user("daniela.morais@sofist.com.br")))
                .andExpect(status().isOk())
                .andReturn();
}

日志

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext

测试类

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {ValidacaoAPITest.TestConfiguration.class, WithSecurityConfig.class})
@WebAppConfiguration
public class ValidacaoAPITest {
    @EnableWebMvc
    @Configuration
    public static class TestConfiguration {
        Fongo fongo = new Fongo("new server 1");
        DB db = fongo.getDB("oknok");

        @Bean
        ValidacaoAPI getValidacaoAPI() {
            return new ValidacaoAPI();
        }

        @Bean
        ActiveUser getActiveUser() {
            ActiveUser mock = Mockito.mock(ActiveUser.class);

            when(mock.getUser()).thenReturn(new User().setEmail("email@email.com"));
            when(mock.getInstancia()).thenReturn(new Instancia().setInstancia("instancia"));
            return mock;
        }

        @Bean
        ValidacaoService getValidacaoService() {
            return new ValidacaoService();
        }

        @Bean
        MatchService getMatchService() {
            return new MatchService();
        }

        @Bean
        PlanilhaReader getPlanilhaReader() {
            return new PlanilhaReader();
        }


        @Bean
        AtributoReader getAtributoReader() {
            return new AtributoReader();
        }

        @Bean
        AtributoDAO getAtributoDAO() {
            return new AtributoDAO();
        }

        @Bean
        UploadService getUploadService() {
            return new UploadService();
        }


        @Bean
        ValidacaoResultadoDAO getValidacaoResultadoDAO() {
            return new ValidacaoResultadoDAO(db);
        }


        @Bean
        Mapper getMapper() {
            return new Mapper(db);
        }

        @Bean
        UploadDAO getUploadDAO() {
            return new UploadDAO(db);
        }

        @Bean
        MatchDAO getMatchDAO() {
            return new MatchDAO(db);
        }

        @Bean
        ValidacaoDAO getValidacaoDAO() {
            return new ValidacaoDAO(db);
        }

        @Bean
        UploadOriginalsDAO getUploadOriginalsDAO() {
            return new UploadOriginalsDAO(db);
        }

        @Bean
        AtributoValidator getAtributoValidator() {
            return new AtributoValidator();
        }

    }

    @Autowired
    MatchService matchService;

    @Autowired
    private WebApplicationContext context;

    private MockMvc mockMvc;

    private static String id;

    @Before
    public void setup() {
        mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
    }

    @Test
    public void testACreateValidation() throws Exception {
        MvcResult result = this.mockMvc
                .perform(post("/api/validacao"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.id", notNullValue()))
                .andReturn();
        this.id = ((BasicDBObject) JSON.parse(result.getResponse().getContentAsString())).getString("id");
    }

    @Test
    public void testBRetrieveAll() throws Exception {
        MvcResult result = this.mockMvc
                .perform(get("/api/validacao"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.[0].id", notNullValue()))
                .andReturn();

        BasicDBList list = (BasicDBList) JSON.parse(result.getResponse().getContentAsString());
        this.id = (String) ((BasicDBObject) JSON.parse(list.get(0).toString())).get("id");
    }

    //FIXME
    @Test
    @WithMockUser(roles = "ADMINISTRADOR")
    public void testCRetrieve() throws Exception {
            this.mockMvc
                    .perform(get("/api/validacao/" + id).with(user("daniela.morais@sofist.com.br")))
                    .andExpect(status().isOk())
                    .andReturn();
    }

}

最佳答案

Spring 安全Reference, section 10.1声明为了能够测试 spring 安全功能,您需要在您的 MockMvc 对象中集成安全过滤器链,如本示例中的 @Before 设置方法所示。

import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@WebAppConfiguration
public class CsrfShowcaseTests {

    @Autowired
    private WebApplicationContext context;
    private MockMvc mvc;

    @Before
    public void setup() {
        mvc = MockMvcBuilders
            .webAppContextSetup(context)
            .apply(springSecurity())
            .build();
    }

...

}

关于java - 使用 Spring Security 进行集成测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30536710/

相关文章:

spring - RESTful Web 服务对于银行应用程序来说是否足够安全?

spring - 通过没有表单登录的 Spring Security 休息基本身份验证

java - 适配器类实现并创建 MouseAdapter 实例

Spring RestTemplate - 覆盖 ResponseErrorHandler

java - 如何将http响应放入Set中

java - 从 Spring MVC Controller 访问服务层

java - 获取 http://localhost:8080/resources/css/index.css net::ERR_ABORTED 404

java - 从主体访问电子邮件 ID,其中身份验证在 Azure Active Directory 中完成

java - 尝试使用 JSON 简单解析 JSON 时出现 NoClassDefFoundError

java - Hibernate 中的月份不是有效月份