отваряне на http връзка зад прокси, което изисква удостоверяване, но не връща 407

Нашият аплет стои зад Microsoft ISA Server, който има интегрирано прокси удостоверяване. Isa Proxy сървърът връща http 405 (НЕ 407) за връзки, които нямат идентификационни данни за удостоверяване. Там за моя клас java.net.Authenticator не се извиква. Как мога да удостоверя връзките си към прокси сървъра в тази ситуация?

Аплетът е подписан и компилиран с java1.6. За връзките се използва клас URLConnection.


person e13420xx    schedule 26.07.2011    source източник
comment
Имате ли директен достъп до HttpURLConnection или е чрез друга библиотека?   -  person laz    schedule 26.07.2011
comment
@laz: да, имам достъп до него.   -  person e13420xx    schedule 26.07.2011


Отговори (1)


Виждам два подхода за заобикаляне на този проблем и нито един от тях не е идеален. Първо, предполагам, че сте потвърдили, че изпращането на заявката с информацията за оторизация не води до код за отговор 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, тогава ще трябва да направите подобни промени за този протокол.

Надяваме се, че едно от тези решения може да бъде полезно за вас. Не съм напълно сигурен, че последният подход ще работи в рамките на ограниченията за сигурност на аплета. Първото обаче трябва. Възможно е също така това да бъде по-лесно да се направи с различна HTTP библиотека като Apache HttpComponents, ако имате възможност да го използвате.

person laz    schedule 26.07.2011
comment
в първия подход заглавката ще бъде прокси-упълномощаване? или Proxy-authentication header?.authentication protocol се различава от време на време (ntlm или kerberos) и поради това този подход ще бъде много труден според мен? в подход две: мислите ли, че задаването на кода за отговор ще бъде достатъчно? Мисля, че също трябва да задам някои заглавки относно какъв вид удостоверяване е необходимо? - person e13420xx; 26.07.2011
comment
Подходът по него ще бъде Proxy-authorization. Изглежда, че ще бъде изключително трудно, ако схемата се промени. Така че връща 405, но не и какъв тип удостоверяване се изисква? В такъв случай, да, вие също ще трябва да включите всички необходими Proxy-Authenticate заглавки на отговор. Прокси сървърът неправилно ли е конфигуриран или нещо подобно? Това звучи като сериозно нарушено поведение! Сървърът работи ли правилно с нещо, като например браузър? - person laz; 26.07.2011
comment
Не знам защо са го конфигурирали така, но това са направили. клиентът в тази мрежа има много ограничен достъп до мрежата, който най-вече сърфира локално. Очевидно не могат да го променят сега поради проблемите, които могат да възникнат поради това, те искат това да бъде решено от страна на клиента. - person e13420xx; 26.07.2011
comment
Мисля, че ще опитам първия подход, който предложих тогава, и ще опитам да създам подходящата стойност на заглавката. - person laz; 26.07.2011