barbitoff programmer`s blog

Здесь я публикую заметки из программерской жизни: грабли, на которые мне случилось наступить, проблемы, для которых было найдено элегантное (или не очень) решение, а также все, с чем мне пришлось столкнуться и чем хотелось бы поделиться =)
PS Если хотите меня поблагодарить - на странице есть 3 места, чтобы это сделать =)

вторник, 4 сентября 2012 г.

jTrust: OnlineCrlRepository и прокси с авторизацией

Онлайн-репозиторий CRL из библиотеки jTrust реализует загрузку CRL-файлов по указанным URL`ам точек распространения сертификатов (CRL Distribution Points). Поддержка прокси в нем есть, и реализуется она передачей объекта NetworkConfig в конструктор класса:
import be.fedict.trust.NetworkConfig;
import be.fedict.trust.crl.OnlineCrlRepository;
// ...
NetworkConfig nwcfg = new NetworkConfig(proxyHost, proxyPort);
OnlineCrlRepository onlineCrlRepo = new OnlineCrlRepository(nwcfg); 
Но такой вариант работает только с прокси-серверами без авторизации.
В тоже время Apache HttpClient, используемый классом OnlineCrlRepository для загрузки файла CRL, авторизацию на прокси поддерживает (не уверен, что все возможные варианты авторизации реализованы, но по крайней мере BASIC есть): http://hc.apache.org/httpclient-3.x/authentication.html#Proxy_Authentication. Но т.к. внутренние поля и методы OnlineCrlRepository являются закрытыми, наследовать его для добавления нового функционала нет особого смысла, приходится копировать исходники в свой класс, добавляя возможность установки авторизации на прокси. 
Для этого я, во-первых, создал специальный класс ProxyCredentials, унаследовав be.fedict.trust.Credentials, предназначенный для хранения данных http-авторизации. Класс  be.fedict.trust.Credentials содержит метод init(), который применяет авторизационные данные к объекту HttpState. Этот метод я и переопределил таким образом, чтобы он задавал не данные авторизации на конечном сайте, а данные авторизации на прокси, заменив вызов httpState.setCredentials() на httpState.setProxyCredentials():
public class ProxyCredentials extends be.fedict.trust.Credentials
{
  @Override
  public void init(HttpState httpState) {
      for (Credential credential : this.getCredentials()) {
        AuthScope authScope = new AuthScope(credential.getHost(),
            credential.getPort(), credential.getRealm(),
            credential.getScheme());
        UsernamePasswordCredentials usernamePasswordCredentials = new UsernamePasswordCredentials(
            credential.getUsername(), credential.getPassword());
        httpState.setProxyCredentials(authScope, usernamePasswordCredentials);
      }
    }
}
Теперь достаточно в нашем варианте класса OnlineCrlRepository добавить поле для хранения объекта ProxyCredentials, setter-метод для этого поля, а также добавить в метод getCrl() применение этих авторизационных данных к объекту HttpState:
public class AdvancedOnlineCrlRepository implements CrlRepository {

  // ..
  protected ProxyCredentials proxyCredentials;
  /**
   * Sets the credentials for proxy authentication
   * @param proxyCredentials
   */
  public void setProxyCredentials(ProxyCredentials proxyCredentials) {
    this.proxyCredentials = proxyCredentials;
  }

  // ..

protected X509CRL getCrl(URI crlUri) throws IOException,
CertificateException, CRLException, NoSuchProviderException,
NoSuchParserException, StreamParsingException {
HttpClient httpClient = new HttpClient();
if (null != this.networkConfig) {
httpClient.getHostConfiguration().setProxy(
this.networkConfig.getProxyHost(),
this.networkConfig.getProxyPort());
}
if (null != this.credentials) {
HttpState httpState = httpClient.getState();
this.credentials.init(httpState);
}
 
if (null != this.proxyCredentials) {
HttpState httpState = httpClient.getState();
this.proxyCredentials.init(httpState);
}
 
String downloadUrl = crlUri.toURL().toString();
//...
return crl;
}
}
Теперь создание объект репозитория CRL для работы с прокси-сервером с авторизацией выглядит так:
NetworkConfig nwcfg = new NetworkConfig(proxyHost, proxyPort);
ProxyCredentials creds = new ProxyCredentials();
Credential cred = new Credential(proxyHost, proxyPort, proxyLogin, proxyPassword);
creds.addCredential(cred);
AdvancedOnlineCrlRepository onlineCrlRepo = new AdvancedOnlineCrlRepository(nwcfg);
onlineCrlRepo.setProxyCredentials(creds);

Комментариев нет:

Отправить комментарий