Skip to content

Cli credentials#7637

Merged
sophiajt merged 10 commits intoAzure:masterfrom
sophiajt:cli_credentials
Mar 5, 2020
Merged

Cli credentials#7637
sophiajt merged 10 commits intoAzure:masterfrom
sophiajt:cli_credentials

Conversation

@sophiajt
Copy link
Copy Markdown
Contributor

@sophiajt sophiajt commented Mar 3, 2020

Taking #6521 and building with the latest master.

With this credential, it's now possible to configure your app to get the logged in credentials via az. If az can't be found, or if the user is not logged in, then the user will get the appropriate error.

Note: this is will become part of the DefaultAzureCredentials

@sophiajt sophiajt marked this pull request as ready for review March 4, 2020 18:30
Comment thread sdk/identity/identity/src/credentials/defaultAzureCredential.ts
Copy link
Copy Markdown
Contributor

@daviwil daviwil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for continuing the work on this credential! Looks good overall aside from some possible improvements to the CredentialClient design.


import * as child_process from "child_process";

export interface CredentialClient {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is specific to the AzureCliCredential I'd call this AzureCliCredentialClient and call the implementation DefaultAzureCliCredentialClient. Since CredentialClient is being exposed on the public interface of this library, it'll be confusing to see something with a more general name than the usage pattern implies.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also needs some basic documentation to make api-extractor happy.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed with the refactor


/**
* Provides the user access token and expire time
* with azure cli command "az account get-access-token" in powershell.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some nits here on casing and removing an inaccuracy about it being invoked via PowerShell.

Suggested change
* with azure cli command "az account get-access-token" in powershell.
* with Azure CLI command "az account get-access-token".

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

.getAzureCliAccessToken(resource)
.then((obj: any) => {
if (obj.stderr) {
let isLoginError = obj.stderr.match("Please run 'az login' to setup account");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let isLoginError = obj.stderr.match("Please run 'az login' to setup account");
let isLoginError = obj.stderr.match("Please run 'az login' from a command prompt to authenticate before using this credential.");

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

obj.stderr.match("az:(.*)not found") ||
obj.stderr.startsWith("'az' is not recognized");
if (isNotInstallError) {
throw new Error("Azure CLI not Installed");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
throw new Error("Azure CLI not Installed");
throw new Error("Azure CLI could not be found. Please visit https://aka.ms/azure-cli for installation instructions and then, once installed, authenticate to your Azure account using 'az login'.");

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's definitely better. Updating

try {
child_process.exec(
`az account get-access-token --output json --resource ${resource}`,
(error, stdout, stderr) => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this interface and class should return an AccessToken, not the pipes from running the command. It'd make mocking and usage easier if it was just handled in the "client" class. What do you think?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind the stdout/stderr approach since it's mocking around the call out to the az.

Copy link
Copy Markdown
Contributor

@daviwil daviwil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new design is much better, thanks a bunch for doing that!

this.getAzureCliAccessToken(resource)
.then((obj: any) => {
if (obj.stderr) {
let isLoginError = obj.stderr.match("Please run 'az login' from a command prompt to authenticate before using this credential.");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know this API, so I have to ask: is this checking whether stderr contains that literal?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like it's a regex match. I might just change it to look for the 'az login' part.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

protected async getAzureCliAccessToken(resource: string) {
return new Promise((resolve, reject) => {
try {
child_process.exec(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To address security concerns, in .NET and Python we use a working directory on the path.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I missed this comment, but I can do a follow-up PR

@sophiajt sophiajt merged commit c5dcaee into Azure:master Mar 5, 2020
@sophiajt sophiajt deleted the cli_credentials branch March 5, 2020 02:03
@sophiajt sophiajt mentioned this pull request Mar 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants