Ответ 1
Я искал то же самое, о чем вы просите. До сих пор я не нашел способ 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 code. Из документа :
-Xbootclasspath: bootclasspath Укажите список каталогов, JAR-архивов и ZIP-архивов, разделенных точкой с запятой, для поиска загрузочного класса файлы. Они используются вместо файлов классов загрузки, включенных в Java 2 SDK. Примечание. Приложения, которые используют этот параметр для целей переопределение класса в rt.jar не следует развертывать, так как это противоречит лицензии двоичного кода Java 2 Runtime Environment.
Таким образом, это определенно не подходит для производственных сред.
Наконец, это отличный источник информации о параметре пути к загрузочному классу и загрузчикам классов Java: PDF
Надеюсь, что это поможет.