Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BotFrameworkAdapter always builds Connector with MicrosoftAppCredentials (never CertificateAppCredentials) -- certificate auth flow broken #3246

Closed
Zerryth opened this issue Jan 30, 2021 · 3 comments · Fixed by #3247
Labels
bug Indicates an unexpected problem or an unintended behavior.
Milestone

Comments

@Zerryth
Copy link
Contributor

Zerryth commented Jan 30, 2021

Versions

What package version of the SDK are you using.: fresh clone of repo, so 4.11.x/ 4.12.x
What nodejs version are you using: v.12.18.4
What os are you using: Windows 10

Describe the bug

Ever since R7, the SDK has supported client certificate authentication, instead of only allowing auth with app ID and password.
However it looks like this functionality is now broken.


Talk to echo bot with certificate authentication setup -- fails:

Call Stack (it's late and too tired to make a sequence diagram, so here's a lot of text!)
  • On instantiation of BotFrameworkAdapter

    • ctor properly creates CertificateAppCredentials and saves to this.credentials if certificate thumbprint and private key are provided
  • incoming message to /api/messages

    • BotFrameworkAdapter.processActivity
      • Create ConnectorClient (this.createConnectorClientWithIdentity)

        • credentials = this.buildCredentials
          • Always creates a new MicrosoftAppCredentials instance, despite any certificate options that may be in BotFrameworkAdapterSettings
        • this.createConnectorClientInternal(serviceUrl, credentials)
          • This will create a ConnectorClient with the passed in MicrosoftAppCredentials
      • Save connector to turn state

      • Request propagates through middleware, then to bot

        • In bot -- context.sendActivity('Echo: Ello, chum.');
          • Eventually calls BotFrameworkAdapter.sendActivities
            • Get ConnectorClient to make outbound request from bot this.getOrCreateConnectorClient
              • If we are making the outbound request with the same instance of BotFrameworkAdapter as we used for the inbound message request, then this will get the ConnectorClient in turn state--the one with MicrsofotAppCredentials
              • Flow is not broken if there isn't any ConnectorClient in turn state (e.g. we use a separate instance for inbound/outbound requests to and from bot). This scenario is not the default scenario that most customers use.

From here things break.

Uh-oh.

(node:22600) UnhandledPromiseRejectionWarning: Error: BotFrameworkAdapter.processActivity(): 500 ERROR
 Error: The clientSecret parameter is required.
    at Object.validateStringParameter (C:\BF\js\to-msal\botbuilder-js\libraries\botframework-connector\node_modules\adal-node\lib\argument.js:37:13)
    at AuthenticationContext.acquireTokenWithClientCredentials (C:\BF\js\to-msal\botbuilder-js\libraries\botframework-connector\node_modules\adal-node\lib\authentication-context.js:282:14)
    at C:\BF\js\to-msal\botbuilder-js\libraries\botframework-connector\lib\auth\microsoftAppCredentials.js:49:48
    at new Promise (<anonymous>)
    at MicrosoftAppCredentials.<anonymous> (C:\BF\js\to-msal\botbuilder-js\libraries\botframework-connector\lib\auth\microsoftAppCredentials.js:48:40)
    at Generator.next (<anonymous>)
    at C:\BF\js\to-msal\botbuilder-js\libraries\botframework-connector\lib\auth\microsoftAppCredentials.js:15:71
    at new Promise (<anonymous>)
    at __awaiter (C:\BF\js\to-msal\botbuilder-js\libraries\botframework-connector\lib\auth\microsoftAppCredentials.js:11:12)
    at MicrosoftAppCredentials.refreshToken (C:\BF\js\to-msal\botbuilder-js\libraries\botframework-connector\lib\auth\microsoftAppCredentials.js:46:16)
    at BotFrameworkAdapter.<anonymous> (C:\BF\js\to-msal\botbuilder-js\libraries\botbuilder\lib\botFrameworkAdapter.js:738:27)
    at Generator.throw (<anonymous>)
    at rejected (C:\BF\js\to-msal\botbuilder-js\libraries\botbuilder\lib\botFrameworkAdapter.js:13:65)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)

It's complaining that there isn't an app password, however when using a certificate to authenticate, app passwords are not used.

To Reproduce

  1. Create certificate for bot. You can use whatever library you want, I used OpenSSL to create the cert.
  2. Upload certificate in the app registration for bot
    image
  3. Run certificate-using bot.
    • I just used 02.echo-bot and created BotFrameworkAdapter with certificate settings applied
const pem = require('pem');
const fs = require('fs');

pem.config({
    pathOpenSSL: '<Path to OpenSSL>'
});

const pfx = fs.readFileSync('<Path to pfx -- this has the certificate you uploaded to Azure bundled in>');
pem.readPkcs12(pfx, { p12Password: 'my-super-secret-password' }, (err, cert) => {
    if (err) {
        console.log(err);
        return;
    }
    
    const adapter = new BotFrameworkAdapter({
        appId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
        certificateThumbprint: '460Dxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx5F53',
        certificatePrivateKey: cert.key
    });

Expected behavior

For auth with certificate to work and not throw error if no app password provided.

@Zerryth Zerryth added bug Indicates an unexpected problem or an unintended behavior. needs-triage The issue has just been created and it has not been reviewed by the team. labels Jan 30, 2021
@Zerryth Zerryth changed the title BotFrameworkAdapter always builds MicrosoftAppCredentials (never CertificateAppCredentials) -- certificate auth flow broken BotFrameworkAdapter always builds Connector MicrosoftAppCredentials (never CertificateAppCredentials) -- certificate auth flow broken Jan 30, 2021
@Zerryth Zerryth changed the title BotFrameworkAdapter always builds Connector MicrosoftAppCredentials (never CertificateAppCredentials) -- certificate auth flow broken BotFrameworkAdapter always builds Connector with MicrosoftAppCredentials (never CertificateAppCredentials) -- certificate auth flow broken Jan 30, 2021
@Zerryth Zerryth removed the needs-triage The issue has just been created and it has not been reviewed by the team. label Feb 1, 2021
@Zerryth Zerryth added this to the R12 milestone Feb 1, 2021
@jineshjin
Copy link

@Zerryth seems like we have similar issue with cloudadapter. I have been trying to setup service credential with certificate authentication but there is no way I can provide cert config to the cloudadapter for certificate authentication.
Can you please check and confirm?

@jineshjin
Copy link

@johnataylor @JhontSouth @ramfattah Can anyone take a look?

@jineshjin
Copy link

@stevkan

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Indicates an unexpected problem or an unintended behavior.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants