Я искал то же, что вы просите. До сих пор я не нашел в JDK способа сделать это.
Существует запрос на улучшение базы данных ошибок Java. Взгляните на отчет , чтобы узнать, получит ли он ответ от Sun (проголосуйте за отчет, так что, надеюсь, это скоро исправят).
То, что я закончил, было переопределено sun.net.www.protocol.http.NTLMAuthentication
классом. Посмотрев на sun.net.www.protocol.http.HttpURLAuthentication
, я обнаружил, что единственное, что вам нужно изменить, это результат:
NTLMAuthentication.supportsTransparentAuth()
Этот метод имеет жестко возвращаемое значение, true
на платформах Windows и false
в противном случае. Этот код извлечен из JDK, установленного в Windows 7:
static boolean supportsTransparentAuth()
{
return true;
}
Этот метод сообщает, должны ли учетные данные Windows использоваться по умолчанию. Если установлено значение true
, , пользовательский код аутентификатора не будет называться . Смотрите этот фрагмент HttpURLConnection
класса:
//Declared as a member variable of HttpURLConnection
private boolean tryTransparentNTLMServer = NTLMAuthentication.supportsTransparentAuth();
//Inside of getServerAuthentication method.
PasswordAuthentication a = null;
if (!tryTransparentNTLMServer) {
//If set to false, this will call Authenticator.requestPasswordAuthentication().
a = privilegedRequestPasswordAuthentication(url.getHost(), addr, port, url.getProtocol(), "", scheme, url, RequestorType.SERVER);
}
/* If we are not trying transparent authentication then
* we need to have a PasswordAuthentication instance. For
* transparent authentication (Windows only) the username
* and password will be picked up from the current logged
* on users credentials.
*/
if (tryTransparentNTLMServer || (!tryTransparentNTLMServer && a != null)) {
//If set to true or if Authenticator did not return any credentials, use Windows credentials.
//NTLMAuthentication constructor, if receives a == null will fetch current looged user credentials.
ret = new NTLMAuthentication(false, url1, a);
}
Чтобы получить NTLMAuthentication
исходный код, я использовал этот Java-декомпилятор . Открыл rt.jar, расположенный в папке установки JDK, и скопировал нужный код класса.
Затем я просто изменил supportsTransparentAuth
, чтобы вернуть false. Однако было бы очень желательно, чтобы этот метод сначала проверял системное свойство, а затем возвращал true или false на основании этого.
Для компиляции я просто поместил java-файл в структуру папок sun / net / www / protocol / http и запустил:
javac NTLMAuthentication.java
Затем запустите мое приложение, используя:
java -Xbootclasspath:"path/to/your/sun/net/www/protocol/http/classes;normal/JDK/boot/directories"
Это скажет JVM загрузить нашу реализацию NTLMAuthentication
перед той, что в rt.jar. Вы должны быть осторожны, чтобы не пропустить пути загрузки классов по умолчанию с -Xbootclasspath
, иначе будут ClassNotFound
ошибки.
После этого все работало просто отлично.
У этого подхода есть важные недостатки, о которых вам следует знать.
- Существуют угрозы безопасности. Любой может оставить другой файл .class в вашей загрузочной папке и украсть учетные данные пользователя или другую важную информацию.
- Код из пакетов Sun может быть изменен без уведомления и поэтому может быть несовместим с вашими изменениями.
- Если вы развернете этот код, вы нарушите лицензию на использование кода Sun. Из документации :
-Xbootclasspath: bootclasspath Укажите разделенный точкой с запятой список каталогов, JAR-архивов и ZIP-архивов для поиска загрузочного класса.
файлы. Они используются вместо файлов загрузочных классов, включенных в
Java 2 SDK. Примечание. Приложения, использующие этот параметр для
переопределение класса в rt.jar не должно быть развернуто, так как это
противоречат лицензии на двоичный код Java 2 Runtime Environment.
Итак, это определенно не подходит для производственных сред.
Наконец, это отличный источник информации о параметре пути загрузочного класса и загрузчиках классов Java: PDF
Надеюсь, это поможет.