Подключение к учетной записи хранения Azure через прокси-сервер Microsoft Azure Storage SDK для Java
В нашем проекте нам нужно получить доступ к хранилищу BLOB-объектов через прокси-сервер (squid).
Мы планируем использовать Microsoft Azure Storage SDK для Java версии 2.2.0. Но похоже, что настройка прокси не предоставляется API. Единственный способ, которым я мог бы пройти через прокси, это установить свойства системы.
System.setProperty("http.proxyHost", "127.0.0.1");
System.setProperty("http.proxyPort", "3128");
Но это влияет на все сервисы, которые работают на моей JVM, что вредит другим сервисам, которые не должны проходить через Прокси.
Глядя на код Java, это выглядит как com.microsoft.azure.storage.core.BaseRequest.createURLConnection(URI, RequestOptions, UriQueryBuilder, OperationContext). Вызывает java.net.URL.openConnection() без прокси. При использовании java.net.URL.openConnection(Proxy) могли бы обеспечить необходимую поддержку?
Мне кажется, что это не поддерживается?
Я что-то здесь скучаю?
ОБНОВЛЕНИЕ: я открыл проблему по этому вопросу в gaz azure-storage-java, я был бы рад получить ваш вклад, поскольку я хочу предложить для этого запрос на извлечение.
3 ответа
После того, как проблема-48 была открыта мной на основании этого вопроса, а другая проблема была открыта стражем -65, поддержка прокси была улучшена в версии 4.2.0, см. Здесь.
Добавлена поддержка настройки прокси для всей библиотеки. Прокси по умолчанию может быть установлен на OperationContext.
См. JUnits для полного примера https://github.com/Azure/azure-storage-java/blob/master/microsoft-azure-storage-test/src/com/microsoft/azure/storage/GenericTests.java
Ищите testDefaultProxy и testProxy
До сих пор не было доступа к поддержке API Java SDK напрямую к хранилищу Azure через прокси-сервер, поскольку в классе BaseRequest отсутствует функция "url.openConnection (proxy)" в функции "public static HttpConnection createURLConnection (...)".
По моему опыту, есть два способа помочь вам реализовать функцию доступа.
Во-первых, вы можете использовать API REST хранилища Azure через класс java.net.Proxy для доступа к службе хранилища.
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(host, port));
URLConnection conn = url.openConnection(proxy);
And if you should be authorize proxy user & password, you can do it as the follows:
//Proxy-Authorization: Basic <Base64.encode(user:password)>
String headerKey = "Proxy-Authorization";
String headerValue = "Basic " + Base64.encode(user+":"+password);
conn.setRequestProperty(headerKey, headerValue);
Последнее - это то, что вы можете изменить API Azure SDK и переписать метод "createURLConnection" в классе "BaseRequest" для реализации доступа. Проект Azure Storage SDK v2.2.0 на GitHub находится по https://github.com/Azure/azure-storage-java/tree/v2.2.0/.
Замечания:
общедоступная статическая HttpURLConnection createURLConnection(окончательный URI URI, окончательные параметры RequestOptions, построитель UriQueryBuilder, окончательный OperationContext opContext, прокси-сервер java.net.Proxy)
а также
окончательный HttpURLConnection retConnection = (HttpURLConnection) resourceUrl.openConnection(прокси);
public static HttpURLConnection createURLConnection(final URI uri, final RequestOptions options, UriQueryBuilder builder, final OperationContext opContext, java.net.Proxy proxy) throws IOException, URISyntaxException, StorageException {
if (builder == null) {
builder = new UriQueryBuilder();
}
final URL resourceUrl = builder.addToURI(uri).toURL();
final HttpURLConnection retConnection = (HttpURLConnection) resourceUrl.openConnection(proxy);
if (options.getTimeoutIntervalInMs() != null && options.getTimeoutIntervalInMs() != 0) {
builder.add(TIMEOUT, String.valueOf(options.getTimeoutIntervalInMs() / 1000));
}
// Note: ReadTimeout must be explicitly set to avoid a bug in JDK 6.
// In certain cases, this bug causes an immediate read timeout exception to be thrown even if ReadTimeout is not set.
retConnection.setReadTimeout(Utility.getRemainingTimeout(options.getOperationExpiryTimeInMs(), options.getTimeoutIntervalInMs()));
// Note : accept behavior, java by default sends Accept behavior as text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
retConnection.setRequestProperty(Constants.HeaderConstants.ACCEPT, Constants.HeaderConstants.XML_TYPE);
retConnection.setRequestProperty(Constants.HeaderConstants.ACCEPT_CHARSET, Constants.UTF8_CHARSET);
// Note : Content-Type behavior, java by default sends Content-type behavior as application/x-www-form-urlencoded for posts.
retConnection.setRequestProperty(Constants.HeaderConstants.CONTENT_TYPE, Constants.EMPTY_STRING);
retConnection.setRequestProperty(Constants.HeaderConstants.STORAGE_VERSION_HEADER,
Constants.HeaderConstants.TARGET_STORAGE_VERSION);
retConnection.setRequestProperty(Constants.HeaderConstants.USER_AGENT, getUserAgent());
retConnection.setRequestProperty(Constants.HeaderConstants.CLIENT_REQUEST_ID_HEADER,
opContext.getClientRequestID());
return retConnection;
}
Кстати, вам нужно вызывать вышеуказанный метод в каждом классе CloudXXXClient(CloudBlobClient и т. Д.).
Группа хранения Azure выпустила новый SDK (v10), в котором прокси теперь поддерживается через HttpPipeline. Вы можете разделить конвейер между всеми операциями, передав его в StorageURL или просто использовать в одном Blob, передав его объекту BlobURL.
AnonymousCredentials creds = new AnonymousCredentials();
// Use PipelineOptions to define a retry strategy and a proxy - you can also pass your own HttpClient to this if you like
PipelineOptions po = new PipelineOptions();
// Proxy configuration shown here as a sample
HttpClientConfiguration configuration = new HttpClientConfiguration(
new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", 8888)), false); //pass true if the Proxy endpoint is HTTPS
po.client = HttpClient.createDefault(configuration);
// Create a URI with SAS token, and pass it to the PageBlobURL with an HttpPipeline created by createPipeline method
URL u = new URL("https://myaccount.blob.core.windows.net/mycontainer/myfile?sv=2017-04-17&sr=b&si=14169767-6354-41ed-a99b-c9db8dcc66bc&sig=8NUr%2BSpmRH%2BB2z%2FpQZDPDquTQ7rbgWfE9a6AePLlFT0%3D");
PageBlobURL blobURL = new PageBlobURL(u, PageBlobURL.createPipeline(creds, po));