2014-10-01 10 views
11

Sto provando a eseguire il test di accesso e sicurezza nella mia API REST, quindi cerco di simulare le sequenze di richieste in tempo reale il più vicino possibile.Perché il risultato di Spring MockMvc non contiene un cookie?

La mia prima richiesta sarebbe:

this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac). 
    addFilters(springSecurityFilterChain).build(); 
this.mapper = new ObjectMapper(); 
.... 
MvcResult result=mockMvc.perform(get("/login/csrf")).andExpect(status().is(200)).andReturn(); 
Cookie[] cookies = result.getResponse().getCookies(); 

(Visualizza intera classe pastebin).

Cerco di ottenere qui il cookie per poter accedere con il token CSRF ricevuto in seguito, ma l'array cookies è vuoto!

Tuttavia, se corro la mia domanda e chiamo

curl -i http://localhost:8080/login/csrf 

faccio tornare un'intestazione Set-Cookie e posso usare il cookie (e il token CSRF) in seguito per l'autenticazione.

Quindi la domanda è: come faccio a ottenere da MockMvc un cookie per me?

+1

Come hai fatto a configurare il 'mockMvc'? –

+0

@SotiriosDelimanolis Ho modificato il mio codice nella domanda per dimostrarlo. Quando avrò tempo, inserirò i bit rilevanti della classe di test qui o un pastebin. –

+0

Le parti rilevanti della mia classe di test sono su pastebin: http://pastebin.com/LiNeRFT0 –

risposta

9

ho trovato una soluzione, utilizzando la capacità di estrarre direttamente oggetti di sessione dal MockHttpServletRequest:

session=(MockHttpSession)result.getRequest().getSession(); 

E poi inserendo la sessione direttamente:

req.session(session); 

Il motivo per cui io non sono contento con questa soluzione è che se il mock httpservlet si comporta diversamente dal servlet reale a questo proposito, come posso essere sicuro che si comporti come il servlet reale negli altri casi. Quindi non sto testando l'applicazione stessa, che potenzialmente lascia vuoti nei test.

0

Io lavoro con RestTemplate per testare con i cookie. RestTemplate cookies handler

@RunWith(SpringRunner.class) 
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) 
@Import(RestTemplateWithCookies.class) 
public class ApplicationTest { 

    @LocalServerPort 
    private int port; 

    @Autowired 
    private Environment env; 

    @Autowired 
    private RestTemplateWithCookies restTemplate; 

    @Test 
    public void appTest() throws Exception { 
     HttpHeaders headers = new HttpHeaders(); 
     headers.set("Referer", env.getProperty("allowed_referer")); 
     HttpEntity<String> entity = new HttpEntity<String>("parameters", headers); 
     ResponseEntity<String> response = restTemplate.exchange("http://localhost:" + port + "/[email protected]", HttpMethod.GET, entity, String.class); 
     assertTrue(response.getStatusCode() == HttpStatus.FOUND); 
     HttpCookie c = restTemplate.getCoookies().stream().filter(x -> env.getProperty("server.session.cookie.name").equals(x.getName())).findAny().orElse(null); 
     assertTrue(c != null); 

    } 

} 
0

in base alla risposta del P.Péter un fatto di questo frammento di codice che otterrà e rimettere la sessione automaticamente per ogni richiesta effettuata (MockHttpServletRequestBuilder) su mockMvc.

@Autowired 
private WebApplicationContext webApplicationContext; 

@Autowired 
private Filter springSecurityFilterChain; 

@Before 
public void setUp() throws Exception { 
    final MockHttpServletRequestBuilder defaultRequestBuilder = get("/dummy-path"); 
    this.mockMvc = MockMvcBuilders.webAppContextSetup(this.webApplicationContext) 
      .defaultRequest(defaultRequestBuilder) 
      .alwaysDo(result -> setSessionBackOnRequestBuilder(defaultRequestBuilder, result.getRequest())) 
      .apply(springSecurity(springSecurityFilterChain)) 
      .build(); 
} 

private MockHttpServletRequest setSessionBackOnRequestBuilder(final MockHttpServletRequestBuilder requestBuilder, 
                  final MockHttpServletRequest request) { 
    requestBuilder.session((MockHttpSession) request.getSession()); 
    return request; 
} 

Per una risposta lunga: controllo questa soluzione (la risposta è per la primavera 4): How to login a user with spring 3.2 new mvc testing

Problemi correlati