Blog Post

Modern Work App Consult Blog
2 MIN READ

Enable Client Certificate Auth for Bot Framework App

freistli's avatar
freistli
Icon for Microsoft rankMicrosoft
Nov 02, 2022


In most cases, Bot Framework Apps use Client ID + Client Secret Key to implement Bot Auth against on the registered Azure AD App. If any direct line request sent to this Bot but cannot provide correct Client ID + Client Secret Key (matched, or another correct pair), the Bot app will return unauthorized failure as well.

 

A typical Javascript Bot Framework project, if you set MicrosoftAppPassword and MicrosoftAppId in the .env file, run this bot app, and then use Bot Framework Emulator to access the bot. If Emulator cannot provide the correct secure info, the request will fail with unauthorized errors:

 

message:"The bot's Microsoft App ID or Microsoft App Password is incorrect."

 

 

 

However, some customers have more secure requirements, wonder if the Bot Auth can use Client Certificate instead of secret key, so that they don’t need to put secret key info in the .env file on the bot app side.

 

It is possible on Bot App side with current Bot framework. I used Node JS bot project as a sample.

 

To implement this feature, firstly need to have a certificate. The test certificate can be self-signed. To create self-signed certificate:

 

 

 

$cert=New-SelfSignedCertificate -Subject "CN=flbutauth" -CertStoreLocation "Cert:\CurrentUser\My"  -KeyExportPolicy Exportable -KeySpec Signature
Export-Certificate -Cert $cert -FilePath "C:\temp\selfsign.cer" 
$mypwd = ConvertTo-SecureString -String "<your password>" -Force -AsPlainText
Export-PfxCertificate -Cert $cert -FilePath "C:\temp\selfsign.pfx" -Password $mypwd

 

 

 

And then follow this good  article to get private key file “selfsign.key“, with the thumbprint, to use them in https://github.com/freistli/CertAuthJSBot/blob/main/MyServiceClientCredentialsFactory.js.

 

In the js file, I extend the ServiceClientCredentialsFactory, and generate CertificateAppCredentials.  Replace the default ServiceClientCredentialsFactory here:

https://github.com/freistli/CertAuthJSBot/blob/main/index.js#L31

 

You may notice the BotFrameworkAuthentication class is also extended in this sample project, it is optional for Client Cert Bot Auth, I modified it because want to check client claims. 

 

With above steps, now in .env file we only need to set MicrosoftAppId.

 

Of course, when you use Bot Framework Emulator, still need to provide AppID and AppPassword as it cannot use certificate so far. On Bot Service, we don’t need to change settings to make it work as Bot Connector is trusted by the AAD registered app.

 

For more information, feel free to check this git repository:

freistli/CertAuthJSBot: Node.JS Bot App supports Certificate Auth on Bot App side, and SSO OAuth for users (github.com)

 

Happy Bot Framework Development!

 

Updated Nov 02, 2022
Version 2.0
  • Hallah490's avatar
    Hallah490
    Copper Contributor

    Enabling Client Certificate Authentication for Bot Framework Apps

    Hi Freist Li,

    Thank you for the detailed guide on enabling client certificate authentication for Bot Framework Apps. Here are a few additional tips:

    1. Generating Certificates: Generate a self-signed certificate for testing:

      PowerShell
       
      $cert = New-SelfSignedCertificate -Subject "CN=botauth" -CertStoreLocation "Cert:\CurrentUser\My" -KeyExportPolicy Exportable -KeySpec Signature Export-Certificate -Cert $cert -FilePath "C:\temp\selfsign.cer" $mypwd = ConvertTo-SecureString -String "<your password>" -Force -AsPlainText Export-PfxCertificate -Cert $cert -FilePath "C:\temp\selfsign.pfx" -Password $mypwd
    2. Implementing in Bot Framework: Extend the ServiceClientCredentialsFactory:

      javascript
       
      const { CertificateAppCredentials } = require('botframework-connector'); class MyServiceClientCredentialsFactory extends ServiceClientCredentialsFactory { async createCredentials(appId, audience, loginEndpoint, validateAuthority, certificateThumbprint, privateKey) { return new CertificateAppCredentials(appId, certificateThumbprint, privateKey); } }
    3. Bot Framework Emulator: Note that the Emulator requires AppID and AppPassword, as it doesn’t support certificates.

    4. Integration with Platforms like WhatsApp: For those integrating with TMWhatsApp or similar platforms, similar secure authentication practices can enhance security.

    Thanks again for your insights. Your GitHub example is a valuable resource for the community.

    Best regards,
    Hallah