How to get a token with specific client id without using secrets or certificates in Azure?

104 views Asked by At

In my Azure environment, I have a function (azf-A) that uses a secret from application B to access application C.
The JWT token used by azf-A to connect to C has the following properties:

"aud": "api://ccc-ccc-ccc-ccc" // Api of app C
"appid": "bbb-bbb-bbb-bbb"     // Client id of app B

Application C has set "bbb-bbb-bbb-bbb" as an authorized client id, so the above setup works correctly.

To enhanced security, I want to eliminate the use of secrets or certificates, but still need function A to be able to create a token with "bbb-bbb-bbb-bbb" as its appid (client id) since app C is out of my control and only authorizes app B.

What have I tried so far?

I have explored Azure's Federated Credentials feature, which allows other identities to impersonate the application. However, I'm uncertain about how to implement this approach.

I also tried to implement on-behalf-of flow, but got an exception AADSTS7000114: "Application 'bbb-bbb-bbb-bbb' is not allowed to make application on-behalf-of calls".

1

There are 1 answers

0
tnbit On

I managed to find a solution. Hopefully, this will help anyone with similar needs.

Here's the approach I took:

  1. Created a new managed identity.
  2. Added the identity as user-assigned to function A.
  3. In application B, I created federated credential with the identity's object ID.
  4. Used the following code in function A to create a token:
var managedIdentityAssertion = new ManagedIdentityClientAssertion(UserAssignedId);
var confidentialClientApp = ConfidentialClientApplicationBuilder
    .Create("bbb-bbb-bbb-bbb")
    .WithClientAssertion(async (AssertionRequestOptions options) => await managedIdentityAssertion.GetSignedAssertion(default))
    .Build();
    
var authenticationResult = await confidentialClientApp
  .AcquireTokenForClient(new[] { "api://ccc-ccc-ccc-ccc/.default" })
  .WithTenantIdFromAuthority(AuthorityUri)
  .ExecuteAsync();
  
var token = authenticationResult.AccessToken;