【问题标题】:Connecting to Azure storage account thru proxy server Microsoft Azure Storage SDK for Java通过代理服务器连接到 Azure 存储帐户 Microsoft Azure Storage SDK for Java
【发布时间】:2015-10-24 21:42:57
【问题描述】:

在我们的项目中,我们需要通过代理服务器 (squid) 访问 Blob 存储。

我们计划使用Microsoft Azure Storage SDK for Java version 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) 时可以提供所需的支持吗?

我觉得这不受支持?
我错过了什么吗?

更新:我在 azure-storage-java git 中为此打开了一个 issue,我很乐意收到您的意见,因为我想为此提出一个拉取请求。

【问题讨论】:

    标签: java azure proxy azure-storage azure-blob-storage


    【解决方案1】:

    目前还没有Java SDK API支持通过代理服务器直接访问Azure Storage,因为BaseRequest Class在函数“public static HttpConnection createURLConnection(...)”中错过了“url.openConnection(proxy)”。

    根据我的经验,有两种方法可以帮助您实现访问功能。

    一种是你可以通过java.net.Proxy类使用Azure Storage REST API来访问存储服务。

    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);
    

    最后一个是你可以修改Azure SDK API并覆盖类“BaseRequest”中的“createURLConnection”方法来实现访问。 GitHub 上的 Azure Storage SDK v2.2.0 项目是https://github.com/Azure/azure-storage-java/tree/v2.2.0/

    注意:

    public static HttpURLConnection createURLConnection(final URI uri, final RequestOptions options, UriQueryBuilder builder, final OperationContext opContext, java.net.Proxy 代理)

    final 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, etc) 类中调用上述方法。

    【讨论】:

    • 感谢您的回答,但您的建议将不起作用,因为该方法是静态的,无法覆盖。到目前为止,我发现的唯一选择是创建一个拉取请求并希望 Azure 团队接受它
    • 我将使用REST API编写一个示例程序来展示给您。
    【解决方案2】:

    在我根据这个问题打开的issue-48 和strazh issue-65 打开的附加一个之后,代理支持在4.2.0 版中得到了改进,请参阅here

    添加了对设置库范围代理的支持。默认代理可以 在 OperationContext 上设置。

    查看 JUnit 以获取完整示例 https://github.com/Azure/azure-storage-java/blob/master/microsoft-azure-storage-test/src/com/microsoft/azure/storage/GenericTests.java

    寻找 testDefaultProxy 和 testProxy

    【讨论】:

      【解决方案3】:

      Azure 存储团队发布了一个新的 SDK (v10),现在通过 HttpPipeline 支持代理。您可以通过将管道传递给 StorageURL 来在所有操作之间共享管道,或者通过将管道传递给 BlobURL 对象仅在单个 Blob 中使用。

      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));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-03-17
        • 1970-01-01
        • 2017-05-09
        • 1970-01-01
        • 2022-01-03
        • 2019-02-01
        • 2017-07-15
        相关资源
        最近更新 更多