1

I am having a hard time trying to authenticate against a particular Tenant ID of Azure. The code that I am using is the following one:

public abstract class Azure
{
    private final static String GRAPH = "https://graph.windows.net/";
    private Logger objLogger;
    private String strAccessToken;
    private String strTenantID;
    private String strLogin;
    private String strAuthorize;
    private String strGraph;
    private String strApplicationID;
    private String strUsername;
    private String strPassword;
    public String getAccessToken() throws InvalidKeyException, MalformedURLException, ServiceUnavailableException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, InterruptedException, ExecutionException
    {
        if (this.strAccessToken == null)
        {
            this.setAccessToken();
        }
        return this.strAccessToken;
    }
    private void setAccessToken() throws MalformedURLException, InterruptedException, ExecutionException, ServiceUnavailableException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException
    {
        AuthenticationContext objContext;
        AuthenticationResult objToken;
        ExecutorService objService;
        Future<AuthenticationResult> objFuture;
        objService = null;
        objToken = null;
        try
        {
            objService = Executors.newFixedThreadPool(1);
            objContext = new AuthenticationContext(this.getAuthorize(), false, objService);
            objFuture = objContext.acquireToken(GRAPH, this.getApplicationID(), this.getUsername(), this.getPassword(), null);
            objToken = objFuture.get();
            this.getLogger().info("Connection to Azure ".concat(this.getClass().getSimpleName().toLowerCase()).concat(" successfully stablished"));
        }
        finally
        {
            objService.shutdown();
        }
        if (objToken == null)
        {
            throw new ServiceUnavailableException("Authentication Service is not available");
        }
        this.strAccessToken = objToken.getAccessToken();
    }
    public void setGraph()
    {
        this.strGraph = GRAPH.concat(this.getTenantID());
    }
}

public class Connection1 extends Azure
{
    private static Connection1 objInstance;
    private Connection1() throws ParameterException, IOException, ParserConfigurationException, SAXException
    {
        super();
        this.setTenantID(<Tenant ID>);
        this.setLogin("https://login.microsoftonline.com/".concat(this.getTenantID()));
        this.setAuthorize(this.getLogin().concat("/oauth2/authorize"));
        this.setGraph();
        this.setApplicationID(<Application ID>);
        this.setAccessToken(null);
        this.setUsername(<username>);
        this.setPassword(<password>);
        this.setLogger();
    }
    public static Azure getInstance() throws ParameterException, IOException, ParserConfigurationException, SAXException
    {
        if (objInstance == null)
        {
            objInstance = new Connection1();
        }
        return objInstance;
    }
}

I have two classes Connection1 and Connection2. Connection2 is a copy of Connection1, the only things that I changed are:

1) Tenant ID

2) Application ID

3) Username

4) Password.

With Connection1 I am able to authenticate and retrieve the data without any issues. The issue comes with Connection2, with this one I get the following error:

[pool-3-thread-1] ERROR com.microsoft.aad.adal4j.AuthenticationContext - [Correlation ID: 63cc6344-2bc1-4f61-aaa0-a2f07acb172b] Execution of class com.microsoft.aad.adal4j.AcquireTokenCallable failed.
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

It seems to be a certificate error, so I research a little online, and they recommend to add "DigiCert Baltimore Root" certificate to my certificate store. The certificate is already there. Do you have any idea of how should I face it?

delucaezequiel
  • 483
  • 2
  • 9
  • 26

2 Answers2

1

Actually find the issue. I used TamperData addIn of Firefox and check each redirection to get all the sites with their respective certificates. It seems that there was a change in this particular tenant that instead of using DigiCert Baltimore Root it end on Entrust.net Root

delucaezequiel
  • 483
  • 2
  • 9
  • 26
0

Just according to your error information, there are two blogs below which you can refer to to fix this issue unable to find valid certification path to requested target.

  1. https://www.mkyong.com/webservices/jax-ws/suncertpathbuilderexception-unable-to-find-valid-certification-path-to-requested-target/
  2. http://nodsw.com/blog/leeland/2006/12/06-no-more-unable-find-valid-certification-path-requested-target

The above blogs all used the tool InstallCert to server certificate that can be added to local keystore. Please follow the README of the GitHub repository.

Meanwhile, only my guess, I think a possible reason is resource competition for a certificate store in a JVM. So if you are running Connection1 and Connection2 within a JVM instance, you can try to separately run them on their own standalone JVM instance, or try to copy the JAVA_HOME directory and set a temporary JAVA_HOME & PATH environment variables in command line to run the other Connection2 without any resource shared with them.

Peter Pan
  • 23,476
  • 4
  • 25
  • 43