Azure KeyVaultClient:使用 Java 中的证书进行身份验证

Azure KeyVaultClient: authenticate with a Certificate in Java

我正在尝试从 pfx 证书的 Azure Java SDK 创建一个 KeyVaultClient 对象。我找到了一份关于如何在 C# 中执行此操作的清晰文档,但必须在 Java 中提供有关如何执行此操作的线索。

我能够从用户帐户 keystore 获得 Windows 证书,但我真的不知道要将什么传递给 KeyVaultClient 构造函数。看起来它接受 TokenCredentials 类型的对象,但我找不到任何关于如何实际构建其中一个对象的文档(需要 "token" 和 "scheme")。

听起来您想知道如何使用 Azure SDK for Java 通过带有必需参数 ServiceClientCredentials credentials 的构造方法创建一个 KeyVaultClient 对象,因为 javadoc 说。

这是我的示例代码。

import com.microsoft.azure.AzureEnvironment;
import com.microsoft.azure.CloudException;
import com.microsoft.azure.credentials.ApplicationTokenCredentials;
import com.microsoft.azure.keyvault.KeyVaultClient;
import com.microsoft.azure.management.Azure;
import com.microsoft.rest.credentials.ServiceClientCredentials;

String clientId = "xxxx";
String domain = "xxxx";  // The same as tenant_id
String secret = "xxxx";  // The same as client_secret or keys
AzureEnvironment environment = AzureEnvironment.AZURE;
ServiceClientCredentials credentials = new ApplicationTokenCredentials(clientId, domain, secret, environment);
// New a KeyVaultClient object
KeyVaultClient kvClient = new KeyValutClient(credentials);

作为参考,可以参考Azure官方document to get the parameters clientId, domain & secret on Azure Management portal. More details for the APIs of Azure Java SDK, please view the javadocs

看来我已经接近通过定义这个 class:

来工作了
  class WindowsStoreCertificateCredentials(clientId: String, certificate: X509Certificate, privateKey: PrivateKey) extends KeyVaultCredentials {

def getAuthResult(authority: String, resource: String): AuthenticationResult  = {       
  val service  = Executors.newFixedThreadPool(1)
  val context = new AuthenticationContext(authority, false, service)

  val certificateCredentials = AsymmetricKeyCredential.create(clientId, privateKey, certificate)
  val authResultFuture = context.acquireToken(resource, certificateCredentials, null)
  authResultFuture.get
}

override def doAuthenticate (authority: String, resource: String, scope: String): String = {
  getAuthResult(authority, resource).getAccessToken
}

}

并在使用 java.security.KeyStore 获得证书 X509Certificate 对象和私钥后尝试使用它:

val client = new KeyVaultClient(new WindowsStoreCertificateCredentials(
  id, privateKey, certificate,))

val test = client.getSecret("https:/...")

不幸的是它引发了一个异常:

sun.security.mscapi.RSAPrivateKey cannot be cast to java.security.interfaces.RSAPrivateKey java.lang.ClassCastException:  sun.security.mscapi.RSAPrivateKey cannot be cast to java.security.interfaces.RSAPrivateKey

我在 github AzureAD/azure-activedirectory-library-for-java 上提出了一个问题并提出了一个 pull request 来修复它,待续...

编辑:此问题现已在 AzureAD/azure-activedirectory-library-for-java 的 1.2.0 版中修复。