0 Replies Latest reply on Oct 14, 2017 12:14 AM by ThierryD

    Access to OSISoft Web API across the internet with only kerberos authentication enabled

    ThierryD

      Hello,

       

      A customer using OSISoft gave me the address of a web site where I can browse their OSISoft web services:

      http s://server.domain.com:port/piwebapi/dataservers

       

      I was also given a username (user@domain.com) and password. Using these info and Chrome, I am able to browse the Web API without problems.

       

      When I try to do the same thing from Java code, I get 401 errors.

       

      When I go to http s://server.domain.com:port/piwebapi/system/configuration, it shows that only Kerberos is enabled.

       

      This is the first part that confuses me. I thought Kerberos required a "domain controller in the middle" to work. I am able to access the web site through the internet without sharing a domain controller.

       

      The second part that confuses me is what Chrome does exactly that my Java client doesn't.


      What I really want is to access the Web API through Java. I use the apache http client libraries.

       

      This is the code I tried (from code gathered in various sites):

       

                  String protocol = properties.getProperty("protocol");

                  String host = properties.getProperty("host");

                  String port = properties.getProperty("port");

                  String uri = protocol + "://" + host + ":" + port + "/" + "piwebapi/dataservers";

                  HttpGet httpGet = new HttpGet(uri);

                  String username = properties.getProperty("username");

                  String password = properties.getProperty("password");

                  HttpClient httpClient = getHttpClient(username, password); // see code below

                  ArrayList<String> authPrefs = new ArrayList<>();

                  authPrefs.add(AuthSchemes.KERBEROS); // I tried just about every AuthSchemes option here

                  RequestConfig config = RequestConfig.custom().setTargetPreferredAuthSchemes(authPrefs).setProxyPreferredAuthSchemes(authPrefs).build();

                  httpGet.setConfig(config);

                  HttpResponse httpResponse = httpClient.execute(httpGet);

                  String jsonString = EntityUtils.toString(httpResponse.getEntity());

       

      public static CloseableHttpClient getHttpClient(String username, String password) {

              try {

                  System.setProperty("java.security.auth.login.config", "login.conf");

                  System.setProperty("java.security.krb5.conf", "krb5.conf");

                  System.setProperty("sun.security.krb5.debug", "true");

                  System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");

                 

                  Credentials credentials = new Credentials() {

                      @Override

                      public String getPassword() {

                          return password;

                      }

                      @Override

                      public Principal getUserPrincipal() {

                          return new Principal() {

                              @Override

                              public String getName() {

                                  return username;

                              }

                          };

                      }

                  };

       

       

                  CredentialsProvider provider = new BasicCredentialsProvider();

                  provider.setCredentials(new AuthScope(null, -1, null), credentials);

       

                  // use the TrustSelfSignedStrategy to allow Self Signed Certificates

                  SSLContext sslContext = SSLContextBuilder

                          .create()

                          .loadTrustMaterial(new TrustSelfSignedStrategy())

                          .build();

       

       

                  // we can optionally disable hostname verification.

                  // if you don't want to further weaken the security, you don't have to include this.

                  HostnameVerifier allowAllHosts = new NoopHostnameVerifier();

       

                  // create an SSL Socket Factory to use the SSLContext with the trust self signed certificate strategy

                  // and allow all hosts verifier.

                  SSLConnectionSocketFactory connectionFactory = new SSLConnectionSocketFactory(sslContext, allowAllHosts);

       

                  // finally create the HttpClient using HttpClient factory methods and assign the ssl socket factory

                  return HttpClients

                          .custom()

                          .setSSLSocketFactory(connectionFactory)

                          .setDefaultCredentialsProvider(provider)

                          .build();

              } catch (Exception ex) {

                  Logger.getLogger(HttpClientUtil.class.getName()).log(Level.SEVERE, null, ex);

                  return null;

              }

          }

       

      Help is appreciated !