在需要身份验证但不返回407的代理后面打开HTTP连接



我们的applet是在集成了代理认证的Microsoft ISA Server之后。Isa代理服务器返回http 405(NOT 407)对于没有认证凭证的连接。因为我的java.net.Authenticator类没有被调用。在这种情况下,我如何验证与代理服务器的连接?

Applet是用java1.6签名和编译的。URLConnection级用于连接

我可以看到两种解决这个问题的方法,但都不是很理想。首先,我猜你已经验证了发送带有授权信息的请求不会导致405响应代码?如果答案是肯定的,您可以尝试将请求中的Proxy-authorization标头设置为标头:

URL url = new URL("http://location");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Proxy-authorization", authorizationValue);

该报头的格式将取决于代理服务器所需的授权方案,因此您必须针对您的特定场景进行一些研究。

第二种方法涉及创建一个内部JDK类的子类,以欺骗响应代码来强制使用正常的代理身份验证路径。首先,这是子类:

public class HttpURLConnection extends sun.net.www.protocol.http.HttpURLConnection {
    @Override
    public int getResponseCode() throws IOException {
        int code = super.getResponseCode();
        if (code == HTTP_BAD_METHOD) {
            code = HTTP_PROXY_AUTH;
            responseCode = code;
        }
        return code;
    }
}

当然,这将掩盖任何实际的405响应,因此它可能会产生意想不到的后果。告诉URL对象使用这个需要java.net.URLStreamHandlerFactory的子类:

public class URLStreamHandlerFactory extends java.net.URLStreamHandlerFactory {
    @Override
    URLStreamHandler createURLStreamHandler(String protocol) {
        if (!protocol.equals("http")) {
            return null;
        } else {
            return new java.net.URLStreamHandler {
                protected String proxy;
                protected int proxyPort;
                public Handler () {
                    proxy = null;
                    proxyPort = -1;
                }
                public Handler (String proxy, int port) {
                    this.proxy = proxy;
                    this.proxyPort = port;
                }
                @Override
                protected java.net.URLConnection openConnection(URL u) throws IOException {
                        return openConnection(u, (Proxy)null);
                }
                @Override
                protected java.net.URLConnection openConnection(URL u, Proxy p) throws IOException {
                        return new HttpURLConnection(u, p, this);
                }
                @Override
                protected int getDefaultPort() {
                    return 80;
                }
            }
        }
    }
}

然后你可以在初始化代码中调用URL.setURLStreamHandlerFactory(new URLStreamHandlerFactory());来使用这个对象。我发现这个站点对于了解核心Java类是如何工作的很有用。如果你需要支持HTTPS,那么你需要对该协议进行类似的更改。

希望这些解决方案中的一个对你有用。我不完全确定后一种方法是否能在Applet的安全约束中工作。但前者应该如此。如果你能够使用不同的HTTP库(如Apache HttpComponents),也可能更容易做到这一点。

相关内容

  • 没有找到相关文章

最新更新