2015-12-02 70 views
0

我一直在嘗試編寫一些基本代碼來測試Azure KeyVault。目前(從控制檯日誌中可以看到),我可以進行身份​​驗證,但KeyVaultClient只是因爲[致命錯誤]而失敗:1:1:文件的提前結束。KeyVault集成 - [致命錯誤]:1:1:文件過早結束

似乎有一點缺乏來自微軟的與azure-java-sdk有關的現實世界的例子,所以我承認我一直在竭盡全力地解釋JavaDocs!

16:12:02.391 [main] DEBUG com.example.cli.Main - Launched! 16:12:02.453 [主要] DEBUG escli.AzureAuthenticationResult - Authresult爲gettoken

16:12:02.491 [池-1-螺紋-1] DEBUG cmaad.adal4j.AuthenticationContext - [相關ID: XXXXXXX-XXX-XXX-XXX-XXXXXXX]使用客戶端HTTP頭: x-client-SKU = java; x-client-VER = 1.0.0; x-client-OS = XXXX; x-client-CPU = XXXX;返回客戶端請求-ID =真;客戶請求-ID = XXXXXXX-XXX-XXX-XXX-XXXXXXX;

16:12:02.491 [池-1-螺紋-1] INFO cmaadal4j.AuthenticationAuthority - [相關ID: XXXXXXX-XXX-XXX-XXX-XXXXXXX]實例發現是成功的

16: 12:05.142 [池-1-螺紋-1] DEBUG cmaad.adal4j.AuthenticationContext - [相關ID: XXXXXXX-XXX-XXX-XXX-XXXXXXX]訪問令牌與散列 'ZZZZZZZZZZZZZZZZZZZZZZZZ' 返回

[致命錯誤]:1:1:文件的提前結束 。

16:12:08.135 [主要] ERROR com.example.cli.Main - 空 java.util.concurrent.ExecutionException: com.microsoft.windowsazure.exception.ServiceException:
在 java.util中。 concurrent.FutureTask.report(FutureTask.java:122) 〜[NA:1.8.0_45]

在 java.util.concurrent.FutureTask.get(FutureTask.java:192) 〜[NA:1.8。 0_45]

at com.microsoft.azure.keyvault.FutureAdapter。 get(FutureAdapter.java:53) 〜[azure-keyvault-0.9.0.jar:na]
at com.example.cli.Main.main(Main.java:37)〜[classes /:na]
在 sun.reflect.NativeMethodAccessorImpl.invoke0(本機方法) 〜[NA:1.8.0_45]
在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 〜[NA:1.8.0_45 ]
在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 〜[NA:1.8.0_45]
在java.lang.reflect.Method.invoke(Method.jav a:497) 〜[na:1.8.0_45]
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) [idea_rt。罐子:NA]

引起: com.microsoft.windowsazure.exception.ServiceException:
在> com.microsoft.windowsazure.exception.ServiceException.createFromXml(ServiceException.java:216) 〜[天藍色核-0.9.0.jar:NA]
在 com.microsoft.azure.keyvault.KeyOperationsImpl.sign(KeyOperationsImpl.java:1524) 〜[天藍色-keyvault-0.9.0.jar:NA]
在 com.microsoft.azure.keyvault.KeyOperationsImpl $ 13.call(KeyOperationsImpl.java:1447) 〜[azure-keyvault-0.9.0.jar:na] at> com.microsoft.azure.keyvault.KeyO perationsImpl $ 13.call(KeyOperationsImpl.java:1444) 〜[天藍色-keyvault-0.9.0.jar:NA]
在 java.util.concurrent.FutureTask.run(FutureTask.java:266) 〜[吶:1.8.0_45]
在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 〜[NA:1.8.0_45]
在 java.util.concurrent.ThreadPoolExecutor中$ Worker.run( ThreadPoolExecutor.java:617) 〜[NA:1.8.0_45]
在java.lang.Thread.run(Thread.java:745) 〜[NA:1.8.0_45]

進程退出代碼爲0

package com.example.cli; 

import com.microsoft.azure.keyvault.KeyVaultClient; 
import com.microsoft.azure.keyvault.KeyVaultClientService; 
import com.microsoft.azure.keyvault.models.KeyOperationResult; 
import com.microsoft.azure.keyvault.webkey.JsonWebKeySignatureAlgorithm; 
import com.microsoft.windowsazure.Configuration; 

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 


import java.security.*; 

import java.util.Random; 

import java.util.concurrent.Future; 


public class Main { 

    public static void main(String[] args) { 
     Logger logger = LoggerFactory.getLogger(Main.class); 
     logger.debug("Launched !"); 

     try { 
      byte[] plainText = new byte[100]; 
      new Random(0x1234567L).nextBytes(plainText); 
      MessageDigest md = MessageDigest.getInstance("SHA-256"); 
      md.update(plainText); 
      byte[] digest = md.digest(); 
      Configuration configuration = AzureKVCredentials.createConfiguration(); 
      KeyVaultClient keyVaultClient = KeyVaultClientService.create(configuration); 
      Future<KeyOperationResult> keyOperationPromise; 
      KeyOperationResult keyOperationResult; 
      keyOperationPromise = keyVaultClient.signAsync("https://XXXXXXX.vault.azure.net/keys/XXXXXXX/XXXXXXX」,JsonWebKeySignatureAlgorithm.RS256,digest); 
      keyOperationResult = keyOperationPromise.get(); // <=== THIS IS LINE 37 IN THE STACKTRACE ;-) <==== 
      byte[] res = keyOperationResult.getResult(); 
      String b64 = java.util.Base64.getEncoder().encodeToString(res); 
      logger.debug(b64); 


     } catch (Exception e) { 
      logger.error(null,e); 
     } 
    } 
} 
+0

您可以嘗試使用Azure REST API來管理密鑰保險庫嗎?https://msdn.microsoft.com/library/azure/mt620024.aspx?f=255&MSPPError=-2147217396 –

回答

1

完成對於使用Azure的KeyVault,你可以嘗試使用Azure的REST API來管理和操作的關鍵庫。請參閱Key Vault REST文檔https://msdn.microsoft.com/en-us/library/azure/dn903630.aspx

Key Vault管理和密鑰有兩組API。密鑰操作需要來自不同資源URI的不同訪問令牌。

對於管理apis,資源uri是https://management.core.windows.net/

對於手術apis,資源uri是https://vault.azure.net。 (注意:請注意,在URI末尾沒有符號/

下面是一個示例代碼作爲參考。

package aad.keyvault; 

import java.io.IOException; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.util.concurrent.ExecutionException; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.Future; 

import javax.naming.ServiceUnavailableException; 
import javax.net.ssl.HttpsURLConnection; 

import org.apache.commons.io.IOUtils; 

import com.microsoft.aad.adal4j.AuthenticationContext; 
import com.microsoft.aad.adal4j.AuthenticationResult; 
import com.microsoft.aad.adal4j.ClientCredential; 

public class RestAPISample { 

    private static final String subscriptionId = "<subscription_id>"; 
    private static final String resourceGroupName = "<resource_group_name>"; 
    private static final String vaultName = "<vault_name>"; 
    private static final String apiVersion = "2015-06-01"; 
    private static final String getKeyVaultInfoUri = String.format(
      "https://management.azure.com/subscriptions/%s/resourceGroups/%s/providers/Microsoft.KeyVault/vaults/%s?api-version=%s", 
      subscriptionId, resourceGroupName, vaultName, apiVersion); 

    private static final String tenantId = "<tenant_id>"; 
    private static final String authority = String.format("https://login.windows.net/%s", tenantId); 
    private static final String clientId = "<client_id>"; 
    private static final String clientSecret = "<client_secret_key>"; 
    private static final String keyName = "<keyvault_key>"; 
    private static final String getInfoFromAKeyUri = String.format("https://%s.vault.azure.net/keys/%s?api-version=%s", 
      vaultName, keyName, apiVersion); 

    public static String getAccessToken(String resource) 
      throws MalformedURLException, InterruptedException, ExecutionException, ServiceUnavailableException { 
     AuthenticationContext context = null; 
     AuthenticationResult result = null; 
     ExecutorService service = null; 
     try { 
      service = Executors.newFixedThreadPool(1); 
      context = new AuthenticationContext(authority, true, service); 
      ClientCredential credential = new ClientCredential(clientId, clientSecret); 
      Future<AuthenticationResult> future = context.acquireToken(resource, credential, null); 
      result = future.get(); 
     } finally { 
      service.shutdown(); 
     } 
     String accessToken = null; 
     if (result == null) { 
      throw new ServiceUnavailableException("authentication result was null"); 
     } else { 
      accessToken = result.getAccessToken(); 
      System.out.println("Access Token: " + accessToken); 
     } 
     return accessToken; 
    } 

    public static void getKeyVaultInfo() throws MalformedURLException, IOException, ServiceUnavailableException, 
      InterruptedException, ExecutionException { 
     System.out.println(getKeyVaultInfoUri); 
     HttpsURLConnection conn = (HttpsURLConnection) new URL(getKeyVaultInfoUri).openConnection(); 
     conn.setRequestProperty("Authorization", "Bearer " + getAccessToken("https://management.core.windows.net/")); 
     conn.addRequestProperty("Content-Type", "application/json"); 
     String resp = IOUtils.toString(conn.getInputStream()); 
     System.out.println(resp); 
    } 

    public static void getKeyInfo() throws MalformedURLException, IOException, ServiceUnavailableException, InterruptedException, ExecutionException { 
     System.out.println(getInfoFromAKeyUri); 
     HttpsURLConnection conn = (HttpsURLConnection) new URL(getInfoFromAKeyUri).openConnection(); 
     conn.setRequestProperty("Authorization", "Bearer " + getAccessToken("https://vault.azure.net")); 
     conn.addRequestProperty("Content-Type", "application/json"); 
     String resp = IOUtils.toString(conn.getInputStream()); 
     System.out.println(resp); 
    } 

    public static void main(String[] args) 
      throws InterruptedException, ExecutionException, ServiceUnavailableException, IOException { 
     getKeyVaultInfo(); 
     getKeyInfo(); 
    } 

} 

Azure的主要庫操作的API需要使用命令set-policy設置好的不同的權限。例如Get information about a keyhttps://msdn.microsoft.com/en-us/library/azure/dn878080.aspx),它需要通過使用Azure CLI cmd azure keyvault set-policy --vault-name <vault-name> --spn <service-principal-no.> --perms-to-keys '["get"]'向密鑰添加權限get來獲得密鑰/獲取權限。

1

您的代碼適用於我,因此我懷疑您的憑據對象(您沒有提供)無效。特殊情況下,請確保使用KeyVaultConfiguration實例。

這是你的AzureKVCredentials我的工作版本:

package com.example.cli; 

import java.util.*; 
import java.util.concurrent.*; 

import com.microsoft.aad.adal4j.*; 
import org.apache.http.*; 
import org.apache.http.message.*; 

import com.microsoft.azure.keyvault.*; 
import com.microsoft.azure.keyvault.authentication.*; 
import com.microsoft.windowsazure.*; 
import com.microsoft.windowsazure.core.pipeline.filter.*; 

public class AzureKVCredentials extends KeyVaultCredentials { 

    public static Configuration createConfiguration() { 
     return KeyVaultConfiguration.configure(null, new AzureKVCredentials()); 
    } 

    @Override 
    public Header doAuthenticate(ServiceRequestContext request, Map<String, String> challenge) { 
     try { 
      String authorization = challenge.get("authorization"); 
      String resource = challenge.get("resource"); 
      AuthenticationResult authResult = getAccessToken(authorization, resource); 
      return new BasicHeader("Authorization", authResult.getAccessTokenType() + " " + authResult.getAccessToken()); 
     } catch (Exception ex) { 
      throw new RuntimeException(ex); 
     } 
    } 

    private static AuthenticationResult getAccessToken(String authorization, String resource) throws Exception { 

     String clientId = "<app id of your Azure application>"; 
     String clientKey = "<application key>"; 

     AuthenticationResult result = null; 
     ExecutorService service = null; 
     try { 
      service = Executors.newFixedThreadPool(1); 
      AuthenticationContext context = new AuthenticationContext(authorization, false, service); 
      Future<AuthenticationResult> future = null; 
      ClientCredential credentials = new ClientCredential(clientId, clientKey); 
      future = context.acquireToken(resource, credentials, null); 
      result = future.get(); 
     } finally { 
      service.shutdown(); 
     } 
     if (result == null) { 
      throw new RuntimeException("authentication result was null"); 
     } 
     return result; 
    } 

} 

這個代碼是基於these sources從Azure的SDK換爪哇。

相關問題