Используя аутентификацию соединения с помощью токена OAuth2, как я могу исправить ошибку «Уже подключено» при отправке зJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Используя аутентификацию соединения с помощью токена OAuth2, как я могу исправить ошибку «Уже подключено» при отправке з

Сообщение Anonymous »

В контексте SpringBoot я использую WebServiceTemplate для выполнения запроса SOAP к различным удаленным ресурсам. До сих пор я использовал базовую аутентификацию для доступа к ним, но для одного из них мне пришлось переключиться на аутентификацию OAuth2.
Короче говоря, мне удалось получить токен OAuth2 (спасибо). на перехватчик) и добавить по моей просьбе. Затем, как указано в документации Spring, я пытаюсь отправить свой запрос через перехватчик.
Затем я вижу два разных пути, но ни один из них в настоящее время не работает. (выдержки кода можно найти в конце описания)
  • либо я пытаюсь получить HttpResponse с помощью httpRequest.execute(). Это не удалось с ошибкой 405. Тело моего POST-запроса может быть неправильным, но я все равно уверен, что оно правильное. Затем, поскольку messageContext не получил ответа, выполняется WebServiceTemplate.sendRequest Spring => возникает ошибка 504 (тайм-аут без дополнительных объяснений :-/). В любом случае, этот путь кажется мне утомительным, поскольку я не вижу четкого способа добавить полученный httpResponse в messageContext. Следовательно, я боюсь, что Spring всегда будет пытаться повторно отправить запрос из WebServiceTemplate.doSendAndReceive, поскольку messageContext.hasResponse() будет оставаться ложным
  • или я использую HttpUrlConnection Connection.send(message) после получения токена OAuth2 и включения его в запрос. Но, похоже, это не удалось (без ошибок), и поскольку messageContext все еще не получил ответа, WebServiceTemplate.doSendAndReceive по-прежнему выполняет соединение.send(request). На этот раз я получаю сообщение об ошибке «Уже подключено». Это кажется логичным, поскольку соединение уже использовалось в перехватчике (безуспешно)
У меня такое ощущение, что второй подход более естественен, чем первый. подразумевает принудительное включение HttpResponse в MessageContext.
Но поскольку ни один из них не работает, я, должно быть, упускаю что-то важное, но, возможно, тривиальное.
Может быть, идея использования перехватчик не так эффективен?
Я был бы искренне признателен, если бы кто-нибудь подсказал мне, что может быть неправильным в моем подходе к этой (должно быть :/) простой задаче. p>
Создание WebServiceTemplate (на заводе)
WebServiceTemplate initTemplate(Destination destination) {
WebServiceTemplate template = new WebServiceTemplate();

template.setMarshaller(marshaller);
template.setUnmarshaller(unmarshaller);
template.setMessageFactory(messageFactory); // messageFactory depends on SOAP version
template.setMessageSender(messageSender);
template.setDefaultUri(destination.getUrl());
template.setInterceptors(new ClientInterceptor[] {new OAuth2WebServiceClientInterceptor(oAuth2TokenInterceptor) });
template.afterPropertiesSet();
return template;
}

OAuth2WebServiceClientInterceptorОпределение
public OAuth2WebServiceClientInterceptor(ClientHttpRequestInterceptor clientHttpRequestInterceptor) {
this.clientHttpRequestInterceptor = clientHttpRequestInterceptor;
}

public boolean handleRequest(MessageContext messageContext) {

HttpUrlConnection connection = (HttpUrlConnection) TransportContextHolder.getTransportContext().getConnection();
SimpleClientHttpRequestFactory simpleClientHttpRequestFactory = new SimpleClientHttpRequestFactory();
try {
ClientHttpRequest httpRequest = simpleClientHttpRequestFactory.createRequest(connection.getUri(), HttpMethod.POST);
// prepare the body to provide it to the intercept method
AxiomSoapMessage message = (AxiomSoapMessage) messageContext.getRequest();
Source soapBody = message.getSoapBody().getPayloadSource();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(soapBody, new StreamResult(byteArrayOutputStream));

byte[] body = byteArrayOutputStream.toByteArray();
httpRequest.getBody().write(body);
ClientHttpResponse response = clientHttpRequestInterceptor.intercept(httpRequest, body,
new ClientHttpRequestExecution() {
@Override
public ClientHttpResponse execute(HttpRequest request, byte[] body)
throws IOException {
ClientHttpResponse response = httpRequest.execute(); // get 405 error
// messageContext.setResponse((AxiomSoapMessage) response); // cast error
return response;
}
});
// connection.send(message); // cause an 'Already connected' error in WebServiceTemplate.doSendAndReceive
} catch (IOException e) {
e.printStackTrace();
return false; // the interceptor has failed.
}
return true;
}

oAuth2TokenInterceptor = компонент, инициированный с помощью этого метода перехвата:
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId("destinationId")
.principal(new AuthenticationPrincipal())
.build();
OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest);

String token = authorizedClient.getAccessToken().getTokenValue();
log.debug("token acquired: " + token);

request.getHeaders().set(HttpHeaders.AUTHORIZATION, "Bearer " + token);
return execution.execute(request, body);
}

Весенняя реализация WebServiceTemplate.doSendAndReceive:
protected T doSendAndReceive(MessageContext messageContext, WebServiceConnection connection,
WebServiceMessageCallback requestCallback, WebServiceMessageExtractor responseExtractor) throws IOException {
int interceptorIndex = -1;
try {
if (requestCallback != null) {
requestCallback.doWithMessage(messageContext.getRequest());
}
// Apply handleRequest of registered interceptors
boolean intercepted = false;
if (interceptors != null) {
for (int i = 0; i < interceptors.length; i++) {
interceptorIndex = i;
if (!interceptors.handleRequest(messageContext)) {
intercepted = true;
break;
}
}
}
// no send/receive if an interceptor has set a response or if the chain
// has been interrupted
if (!messageContext.hasResponse() && !intercepted) {
sendRequest(connection, messageContext.getRequest());
if (hasError(connection, messageContext.getRequest())) {
triggerAfterCompletion(interceptorIndex, messageContext, null);
return (T) handleError(connection, messageContext.getRequest());
}
WebServiceMessage response = connection.receive(getMessageFactory());
messageContext.setResponse(response);
}
logResponse(messageContext);
if (messageContext.hasResponse()) {
if (!hasFault(connection, messageContext.getResponse())) {
triggerHandleResponse(interceptorIndex, messageContext);
triggerAfterCompletion(interceptorIndex, messageContext, null);
return responseExtractor.extractData(messageContext.getResponse());
} else {
triggerHandleFault(interceptorIndex, messageContext);
triggerAfterCompletion(interceptorIndex, messageContext, null);
return (T) handleFault(connection, messageContext);
}
} else {
triggerAfterCompletion(interceptorIndex, messageContext, null);
return null;
}
} catch(Exception e){
/*...*/
}
}


Подробнее здесь: https://stackoverflow.com/questions/790 ... ady-connec
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»