Facing this issue myself, I documented the steps to get there.
1 Set up the resource app and client as usual
So, first, configure the client credentials flow as described here: https://learn.microsoft.com/en-us/azure/active-directory-b2c/client-credentials-grant-flow?pivots=b2c-custom-policy
This is pretty straight forward, up till (and including) step 3.
About step 3: pay attention to this line:
Replace with the full name of your user flow, or custom policy. Note, all types of user flows and custom policies support client credentials flow. You can use any user flow or custom policy you have, or create a new one, such as sign-up or sign-in.
It notes all user flows support client_credentials
, however, although, when targetting a user flow, the API connector (which can normally be used to enrich a token will not be called).
2 Prepare the custom policies
As by documentation, set up signing and encryption keys:
Create the signing key
- Select Policy Keys and then select Add.
- For Options, choose Generate.
- In Name, enter TokenSigningKeyContainer. The prefix B2C_1A_ might be added automatically.
- For Key type, select RSA.
- For Key usage, select Signature.
Select Create.
Create the encryption key
- Select Policy Keys and then select Add.
- For Options, choose Generate.
- In Name, enter TokenEncryptionKeyContainer. The prefix B2C_1A_ might be added automatically.
- For Key type, select RSA.
- For Key usage, select Encryption.
- Select Create.
Upload base policies
Install the base policies from the starter pack, also see github
There are several similar files, but the ones under LocalAccounts are sufficient for just enriching the JWT.
Make sure you replace the tenant name with yours.
Upload these into the custom policies.
3 Upload the ClientCredentialsFlow
The ClientCredentialsFlow.xml policy can now be uploaded. Make sure you replace the tenant name with yours.
Login using application client ID and secret
Login and you should receive an enriched token. You can start customizing the example policy accordingly.
url = "https://<yourtenant>.b2clogin.com/<yourtenant>.onmicrosoft.com" +
"/B2C_1A_DEMO_CLIENTCREDENTIALSFLOW/oauth2/v2.0/token"
#the scope as described,typically it looks like this
scope = "https://<yourtenant>.onmicrosoft.com/<resource server id>/.default"
response = requests.post( url,
data={'grant_type':'client_credentials',
'client_id':client,
'client_secret':secret,
'scope':scope},
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
)