Azure KeyVaultClient: authenticate with a Certificate in Java

1.6k views Asked by At

I am trying to create a KeyVaultClient object from the Azure Java SDK from a pfx certificate. I found a clear document on how to do that in C# but have to clue how to do it in Java.

I am able to get a Windows certificate from the user account keystore, but I do not really know what to pass to the KeyVaultClient constructor. It looks like it accepts object of type TokenCredentials, but I cannot find any document on how to actually build one of those (which needs a "token" and a "scheme").

2

There are 2 answers

0
CanardMoussant On BEST ANSWER

It seems I am close to have something working by defining this 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
}

}

And trying to use it after getting a certificate X509Certificate object and private key using java.security.KeyStore:

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

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

Unfortunately it raises an exception:

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

I opened an issue on github AzureAD/azure-activedirectory-library-for-java and proposed a pull request to fix it, to be continued...

Edit: this is now fixed in version 1.2.0 of AzureAD/azure-activedirectory-library-for-java.

1
Peter Pan On

It sounds like you want to know how to use Azure SDK for Java to create a KeyVaultClient object via the constructor method with the required parameter ServiceClientCredentials credentials, as the javadoc said.

Here is my sample code.

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);

As reference, you can refer to the Azure offical 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