Skip to content
This repository has been archived by the owner on May 5, 2023. It is now read-only.

Azure Function: Credentials not working in keyVault class #5117

Closed
saikrishnav opened this issue Aug 26, 2019 · 3 comments
Closed

Azure Function: Credentials not working in keyVault class #5117

saikrishnav opened this issue Aug 26, 2019 · 3 comments

Comments

@saikrishnav
Copy link

saikrishnav commented Aug 26, 2019

I am writing an AzureFunction where the function has access to key vault. In the function, I am trying to retrieve the secrets from the keyvault.

While doing that, I am getting below error:
Exception: Error: credentials must be one of: ApplicationTokenCredentials, UserTokenCredentials, DeviceTokenCredentials, MSITokenCredentials Stack: Error: credentials must be one of: ApplicationTokenCredentials, UserTokenCredentials, DeviceTokenCredentials, MSITokenCredentials at KeyVaultCredentials.authenticator (D:\home\site\wwwroot\node_modules\azure-keyvault\node_modules\ms-rest-azure\lib\credentials\keyVaultCredentials.js:65:16)

My Azure Function Trigger Code is this:
`
import { AzureFunction, Context, HttpRequest } from "@azure/functions";
import * as msrestazure from "ms-rest-azure";
import * as keyvault from "azure-keyvault";

const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise {
context.log('HTTP trigger function processed a request.');
const name = (req.query.name || (req.body && req.body.name));
if (name) {
const keyVaultName = req.query.name;
const secretName = req.query.key;
const vaultUri = https://${keyVaultName}.vault.azure.net/;

    let keyVaultClient: any;
    if (process.env.APPSETTING_WEBSITE_SITE_NAME){
        let credentials = await msrestazure.loginWithAppServiceMSI();
        keyVaultClient = new keyvault.KeyVaultClient(credentials);
      } else {
        let credentials = await msrestazure.loginWithServicePrincipalSecret(process.env["CLIENT_ID"], 
            process.env["CLIENT_SECRET"], process.env["TENANT_ID"]);
        keyVaultClient = new keyvault.KeyVaultClient(credentials);
      }
    const secretBundle = await keyVaultClient.getSecret(vaultUri, secretName, "");
    const secretValue = secretBundle.value;
    context.log(secretValue);

    context.res = {
        // status: 200, /* Defaults to 200 */
        body: "Hello " + secretValue
    };
}
else {
    context.res = {
        status: 400,
        body: "Please pass a name on the query string or in the request body"
    };
}

};

export default httpTrigger;`

My TSConfig is set to "ES6"
Here's package.json:
{ "name": "", "version": "1.0.0", "description": "", "dependencies": { "azure-keyvault": "^3.0.4", "ms-rest-azure": "^3.0.0" }, "devDependencies": { "@azure/functions": "^1.0.2-beta2", "typescript": "^3.3.3" } }

@saikrishnav
Copy link
Author

It works in your sample, but not in my TypeScript compiled code.
Issue is in the "keyVaultCredentials.js" of the "azure-keyvault" library. In authenticationMapper, we have below code:

if (credentials instanceof ApplicationTokenCredentials) { return context.acquireTokenWithClientCredentials( challenge.resource, credentials.clientId, credentials.secret, _formAuthorizationValue); } else if (credentials instanceof UserTokenCredentials) { return context.acquireTokenWithUsernamePassword( challenge.resource, credentials.username, credentials.password, credentials.clientId, _formAuthorizationValue); } else if (credentials instanceof DeviceTokenCredentials) { return context.acquireToken( challenge.resource, credentials.username, credentials.clientId, _formAuthorizationValue); } else if (credentials instanceof MSITokenCredentials) { return credentials.getToken(_formAuthorizationValue); } else { callback(new Error('credentials must be one of: ApplicationTokenCredentials, UserTokenCredentials, ' + 'DeviceTokenCredentials, MSITokenCredentials')); }

"instanceof" check is failing even though my credentials object is "MSIAppTokenCredentials" object. In Local Dev environbment as well, "instanceof" check is failing even though credentials is "ApplicationTokenCredentials" object. For some reason, the "instanceof" check is failing after compilation to javascript from typescript in azure function.

If I comment out "instanceof" check, then it works.

@michaeljqzq
Copy link
Contributor

Actually for the keyvault service, the node SDK is going to be deprecated and won't have new feature and releases. Instead, the new versions are released here: https://www.npmjs.com/package/@azure/keyvault-secrets https://www.npmjs.com/package/@azure/keyvault-keys . You can have a try with the new SDK. And feel free to give feedback if that won't work or have further issues.

@saikrishnav
Copy link
Author

@michaeljqzq - I did find @azure/keyvault-secrets eventually. But it has another bug that prevents me from using it.
Any case, I will followup on below bug, and close this one.
Azure/azure-sdk-for-js#4631

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants