Получение токена доступа Azure для немецкого облака

У меня есть небольшая программа, которая дает сбой при попытке получить токен доступа для немецкого облака Azure.

public static String generateAccessToken(AzureAccount accountValue) throws MalformedURLException, InterruptedException,
                    ExecutionException, ServiceUnavailableException {
        AuthenticationContext context;
        ExecutorService service = null;
        try {
            String tenantId = accountValue.getTenant();
            String ClientID = accountValue.getClient();
            String secretKey = accountValue.getKey();
            service = Executors.newFixedThreadPool(1);
            context = new AuthenticationContext(
                                                "https://login.microsoftonline.de/" + tenantId
                                                + "/oauth2/authorize", false,
                                                service);

            ClientCredential cred = new ClientCredential(ClientID, secretKey);
            Future<AuthenticationResult> future =
                                                context.acquireToken("https://management.microsoftazure.de", cred,
                                                                     null);
            AuthenticationResult authenticationResult = future.get();
            if (authenticationResult == null) {
                throw new ServiceUnavailableException("authentication result was null");
            }
            System.out.println("Bearer " + authenticationResult.getAccessToken());
            return "Bearer " + authenticationResult.getAccessToken();
        }
        finally {
            service.shutdown();
        }
    }

Код правильно работает для общего облака Azure, но не работает для немецкого облака.

Это трассировка стека

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
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1283)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1258)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250)
    at com.microsoft.aad.adal4j.AdalOAuthRequest.configureHeaderAndExecuteOAuthCall(AdalOAuthRequest.java:140)
    at com.microsoft.aad.adal4j.AdalOAuthRequest.send(AdalOAuthRequest.java:83)
    at com.microsoft.aad.adal4j.AdalTokenRequest.executeOAuthRequestAndProcessResponse(AdalTokenRequest.java:80)
    at com.microsoft.aad.adal4j.AuthenticationContext.acquireTokenCommon(AuthenticationContext.java:818)
    at com.microsoft.aad.adal4j.AuthenticationContext.access$100(AuthenticationContext.java:66)
    at com.microsoft.aad.adal4j.AuthenticationContext$1.call(AuthenticationContext.java:174)
    at com.microsoft.aad.adal4j.AuthenticationContext$1.call(AuthenticationContext.java:163)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
    at sun.security.validator.Validator.validate(Validator.java:260)
    at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1491)
    ... 23 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
    ... 29 more
java.util.concurrent.ExecutionException: 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
    at java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.util.concurrent.FutureTask.get(FutureTask.java:192)
    at com.vmturbo.mediation.azure.Runner.generateAccessToken(Runner.java:127)
    at com.vmturbo.mediation.azure.Runner.main(Runner.java:79)
Caused by: 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
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1283)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1258)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250)
    at com.microsoft.aad.adal4j.AdalOAuthRequest.configureHeaderAndExecuteOAuthCall(AdalOAuthRequest.java:140)
    at com.microsoft.aad.adal4j.AdalOAuthRequest.send(AdalOAuthRequest.java:83)
    at com.microsoft.aad.adal4j.AdalTokenRequest.executeOAuthRequestAndProcessResponse(AdalTokenRequest.java:80)
    at com.microsoft.aad.adal4j.AuthenticationContext.acquireTokenCommon(AuthenticationContext.java:818)
    at com.microsoft.aad.adal4j.AuthenticationContext.access$100(AuthenticationContext.java:66)
    at com.microsoft.aad.adal4j.AuthenticationContext$1.call(AuthenticationContext.java:174)
    at com.microsoft.aad.adal4j.AuthenticationContext$1.call(AuthenticationContext.java:163)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
    at sun.security.validator.Validator.validate(Validator.java:260)
    at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1491)
    ... 23 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)

Похоже, он ищет какой-то файл сертификата, о котором я понятия не имею. Кто-нибудь знает об этом?

Также есть ли способ получить токен Azure Access с помощью Azure Java SDK, чтобы мне не приходилось делать отдельный вызов REST API?


person user1142317    schedule 17.07.2017    source источник
comment
Я просматривал бы все файлы в вашем проекте, даже те, которые вы не писали, и искал экземпляры windows.net или microsoftonline.com и убеждался, что в вашем приложении нет конфигураций, указывающих на неправильное облако Azure. Я не уверен на 100% в сообщении об ошибке, но это может быть так же просто, как ваша программа не может проверить подпись на токене в результате того, что вы ищете неправильную конечную точку открытого ключа.   -  person Shawn Tabrizi    schedule 18.07.2017
comment
В вашем коде все в порядке, я просто протестировал его в том виде, в котором он у вас есть, и смог получить токен доступа к API управления Azure Germany. Вы полностью уверены, что именно здесь генерируется исключение (вам не хватает части трассировки стека)? Вы смотрели другие вопросы в StackOverflow относительно этого исключения?   -  person Philippe Signoret    schedule 18.07.2017


Ответы (1)


Это связано с тем, что вы использовали виртуальную машину, не входящую в немецкий диапазон IP-адресов. У вас есть два варианта:

  1. Разверните виртуальную машину в облаке Azure для Германии или в AWS во Франкфурте.
  2. Для развертывания из негерманского местоположения: обновите имеющийся у вас Java SDK (у меня был 1.8.0_92 и обновлен до 1.8.0_144), и это должно работать.
person Jaimy    schedule 09.08.2017
comment
Привет исправил? У меня такая же проблема, и я запускаю виртуальную машину Azure Germany, используя java 1.8.144. - person li-raz; 13.10.2017
comment
да, после этого вам нужно снова установить свой путь java jvm, а затем указать сценарий bash_profile. Ты сделал это? - person Jaimy; 15.10.2017
comment
вы можете проверить, набрав, какой java в терминале - person Jaimy; 15.10.2017
comment
я использую последнюю версию java - 1.8.0.144 - я установил java на чистую машину - person li-raz; 16.10.2017