Home > OS >  Spring Boot RestTemplate get Cookie from Callback
Spring Boot RestTemplate get Cookie from Callback

Time:04-08

I would like to retrieve a jwt token, using Spring RestTemplate, from a callback that is a redirect URL from a login URL.

I have been able to connect to the login URL, I have been able to follow the redirect link to the callback, but I have not been able to retieve the token that is stored in the reponse header of the callback.

RestTemplate restTemplate = new RestTemplate();
String url = my_login_url;

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add(my_login);
map.add(my_password);

HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);

final HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
final HttpClient httpClient = HttpClientBuilder.create()
                .setRedirectStrategy(new LaxRedirectStrategy())
                .build();
factory.setHttpClient(httpClient);
restTemplate.setRequestFactory(factory);

ResponseEntity<String> response = restTemplate.exchange(url,
                HttpMethod.POST,
                request,
                String.class);

// OUCH !! response does not contain the token I'm trying to retrieve !! The token is in the header of the callback !!

Could anybody help me understand how to access the header of the callback ?

CodePudding user response:

After some research, I was able to find a way to retrieve that token, that seems more like a hack to me than an actual solution.
The idea is that the apache HttpClient contains a cookie store with just the token I need. Unfortunately, HttpClient does not have any getters, only execute methods, and I'm already on RestTemplates.
However, it is possible to pass a Cookie Store as a parameter while building the HttpClient instance. That Cookie Store will be filled while posting the authentication request.

The final version of the code looks like that:

RestTemplate restTemplate = new RestTemplate();
String url = my_login_url;

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add(my_login);
map.add(my_password);

HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);

final HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
CookieStore basicCookieStore = new BasicCookieStore();
final HttpClient httpClient = HttpClientBuilder.create()
                .setRedirectStrategy(new LaxRedirectStrategy())
                .setDefaultCookieStore(basicCookieStore)
                .build();
factory.setHttpClient(httpClient);
restTemplate.setRequestFactory(factory);

restTemplate.exchange(url,
                HttpMethod.POST,
                request,
                String.class);

Cookie cookie  = basicCookieStore.getCookies().stream()
                .findFirst()
                .orElseThrow(() -> new RuntimeException(url));
System.out.println(cookie.getValue());

Notince that I am not even interested in the response of the restTemplate.exchange query.

CodePudding user response:

You can use

response.getHeaders().get(ResponseEntity.SET_COOKIE);

(While the client sends the cookies it has via the "Cookie" header, the server sends cookies to set with a "Set-Cookie" header.)

This returns a list because each cookie will be in an extra header with the same name.

  • Related