Мне нужно получить jwt-токен по логин-паролю.
curl выглядит вот так:
curl --location --request POST 'https://path/to/auth/service' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'username=DOMAIN\username' \
--data-urlencode 'password=password' \
--data-urlencode 'client_id=441345C435-23433454V5FC-34TVRVT5VT' \
--data-urlencode 'resource=https://path/to/resource'
Я выполняю запрос с http-клиентом IDEA, он выглядит вот так:
POST https://path-to-auth-service
Content-Type: application/x-www-form-urlencoded
grant_type=password&username=DOMAIN\username&password=password&client_id=441345C435-23433454V5FC-34TVRVT5VT&resource=https%3A%2F%path%2to%2resource
Я получил токены, выполнив этот запрос, без проблем. Но мне нужно сделать это с помощью RestTemplate. Мне нужен был локально подписанный сертификат, мой bean-компонент restTemplate выглядит вот так:
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial(null, acceptingTrustStrategy)
.build();
SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(csf)
.build();
HttpComponentsClientHttpRequestFactory requestFactory =
new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
var restTemplate = new RestTemplate(requestFactory);
List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.ALL));
messageConverters.add(mappingJackson2HttpMessageConverter);
restTemplate.setMessageConverters(messageConverters);
return restTemplate;
}
При этих настройках ошибка сертификата исчезла, хорошо. Код для подготовки запроса:
public ResponseEntity<AuthResponse> getTokenByLoginPasswordPair(AuthProperties properties) {
HttpEntity<?> authEntity = createAuthEntity(createGetTokenParams(properties));
return restTemplate.exchange(
url,
HttpMethod.POST,
authEntity,
AuthResponse.class
);
}
private HttpEntity<?> createAuthEntity(MultiValueMap<String, String> params) {
var httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
return new HttpEntity<>(params, httpHeaders);
}
private MultiValueMap<String, String> createGetTokenParams(AuthProperties properties) {
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("grant_type", "password");
params.add("username", properties.getUsername());
params.add("password", properties.getPassword());
params.add("client_id", properties.getClientId());
params.add("resource", URLEncoder.encode(properties.getResource(), StandardCharsets.UTF_8));
return params;
}
Я получил html -страницу с сообщением об ошибке. Когда RestTemplate.doExecute () остановился на точке останова response = request.execute();
, запрос выглядит как ByteArrayOutputStream:
{"grant_type":["password"],"username":["DOMAIN\\username"],"password":["password"],"client_id":["441345C435-23433454V5FC-34TVRVT5VT"],"resource":["https%3A%2F%path%2to%2resource"]}
, идентично запросу HTTP-клиента IDEA. В случае запроса http-клиента я получаю ту же страницу с ошибкой при попытке отправить
username=DOMAIN\username&password=password&client_id=441345C435-23433454V5FC-34TVRVT5VT&resource=https%3A%2F%path%2to%2resource
без grant_type=password
.
Может быть, я неправильно оформляю форму application/x-www-form-urlencoded
? Пожалуйста, помогите.