1
votes

I want to connect to get Key Vault secrets using Azure AD client certificate

The example https://github.com/Azure-Samples/key-vault-java-certificate-authentication is not working for me.

Scenario steps:

1.Registered application in Azure AD, Added API/Permission name - Azure Key Vault

Selected user_impersonation. Have full access to Key Vault Service

2.Created certificate - pfx file

  1. Java code from example - specifying client id (registered application client id), pfx file password, pfx file location, key vault url

Question: How does Azure know about the certificate? Never worked with pfx file. Do I need to upload certificate (it says public key .cer/pem/crt)

Can I ask what step I'm missing, as I think authentication is not happening?

java.lang.ClassCastException: class java.lang.String cannot be cast to class java.util.List (java.lang.String and java.util.List are in module java.base of loader 'bootstrap') at com.nimbusds.oauth2.sdk.util.MultivaluedMapUtils.getFirstValue(MultivaluedMapUtils.java:70) at com.nimbusds.oauth2.sdk.auth.JWTAuthentication.ensureClientAssertionType(JWTAuthentication.java:246)

Correction: My application is not in the Azure VM. It is on-premise

Java Code:

I updated the github example code with the below, but the error is same on acquireAccessToken call

AzureAdTokenCredentials credentials = new AzureAdTokenCredentials(
                                        tenant,
                                        AsymmetricKeyCredential.create(clientId, privateKey, certificateKey.getCertificate()),
                                        AzureEnvironments.AZURE_CLOUD_ENVIRONMENT);
                             
TokenProvider provider = new AzureAdTokenProvider(credentials, executorService);

String newToken =  provider.acquireAccessToken().getAccessToken();

                         

java.lang.ClassCastException: class java.lang.String cannot be cast to class java.util.List (java.lang.String and java.util.List are in module java.base of loader 'bootstrap') at com.nimbusds.oauth2.sdk.util.MultivaluedMapUtils.getFirstValue(MultivaluedMapUtils.java:70) at com.nimbusds.oauth2.sdk.auth.JWTAuthentication.ensureClientAssertionType(JWTAuthentication.java:246) at com.nimbusds.oauth2.sdk.auth.PrivateKeyJWT.parse(PrivateKeyJWT.java:277) at com.microsoft.aad.adal4j.AuthenticationContext.createClientAuthFromClientAssertion(AuthenticationContext.java:903)

More Updates:

I see the above error in https://github.com/microsoft/azure-spring-boot/issues/457 and so updated a few of my dependencies and crossed that bridge.

New Error:

enter image description here

enter image description here So I see it is unauthorized? and so too many follow up requests. How I can fix this? Should I use Handling Authentication in Okhttp ? Is this only a cap to avoid error, or guarantee authentication

2
Have you uploaded the public key of the certificate under "Certificates & Secrets" section of your app registration? Also, have you given permission to your registered application to access keys and secrets in the key vault. I believe step 1 (Added API/Permission name - Azure Key Vault) just allows you to get access token for key vault resource type.Gaurav Mantri
ok. I did mention that in the question. The file created is pfx and uploadable file should be .cer/pem/crt. created crt file from pfx and uploaded. I want to know - whether my standalone app was hitting Azure AD or notKris Swat

2 Answers

1
votes

Regarding the issue, please refer to the following steps

  1. Convert pfx to cer with openssl
openssl pkcs12 -in <> -out <> -nodes
  1. Upload the cert to Azure AD application enter image description here

  2. Configure access policy for the application in Azure key vault enter image description here

  3. run the sample.

1
votes

Damn it. I thought AzureAdTokenCredentials will help. Instead that had a side effect. I rolled back my code update after seeing the error in postman

"message": "AKV10022: Invalid audience. Expected https://vault.azure.net, found: https://rest.media.azure.net."

AsymmetricKeyCredential asymmetricKeyCredential = AsymmetricKeyCredential.create(clientId,
                                privateKey, certificateKey.getCertificate());

AuthenticationResult result = context.acquireToken(resource, 
                                asymmetricKeyCredential, null).get();
String newToken = result.getAccessToken();

So this code is surely setting scope, which can be seen in the token

"aud": "https://vault.azure.net",

I followed the article - https://goodworkaround.com/2020/07/07/authenticating-to-azure-ad-as-an-application-using-certificate-based-client-credential-grant/

If anyone is not comfortable with openssl commands etc, then create/generate certificate in Key vault, Download cer / crt from there itself and import to Azure AD registeredApp