0

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

Kris Swat
  • 788
  • 1
  • 10
  • 39
  • 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 Apr 22 '21 at 00:21
  • 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 not – Kris Swat Apr 22 '21 at 12:46

2 Answers2

1

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.

Jim Xu
  • 21,610
  • 2
  • 19
  • 39
  • I am trying to get this working, but not successful. The crux is converting pfx to cer, and I needed to use winpty before openssl. Issue now is adding certificate is failing. Cant figure out the reason, but it is giving a hash [axe....] in the fail message – Kris Swat Apr 22 '21 at 09:06
  • @KrisSwat Sorry I cannot understand your issue. Could you please describe your issue in detail and provide the screenshot of the error? – Jim Xu Apr 22 '21 at 09:11
  • I used a different command to create crt from pfx, and was able to upload. Now Step 3 looks more than the screenshot. I need to select principal. Dont know what this can be, so selected my registered app. Code is not working. so some issue with example, as it doesnt specify tenant id etc – Kris Swat Apr 22 '21 at 09:45
  • you said my first comment was not clear to you. So explaining - when I used cer file using your command , Azure did not accept the file. I created crt using - winpty openssl pkcs12 -in C:\\...\\certm.pfx -clcerts -nokeys -out C:\\...\cekv.crt and this worked – Kris Swat Apr 22 '21 at 12:57
0

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

Kris Swat
  • 788
  • 1
  • 10
  • 39