Azure / azure-cli

Azure Command-Line Interface
MIT License
3.97k stars 2.95k forks source link

Code should be part of url on device-login #21671

Open paulgmiller opened 2 years ago

paulgmiller commented 2 years ago

Is your feature request related to a problem? Please describe.

Currently when I do az login

To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code AWSDQQ7J6 to authenticate.

I have to copy and paste or retype that code into the brower.

Describe the solution you'd like Many terminals including windows terminal let you just click links. If the code was a query argument I'd click https://microsoft.com/devicelogin?code=AWSDQQ7J6 and save several mouse motions a day. (our policies require relogin once a day minimum per device).

Describe alternatives you've considered Let az login send a notification to my phone rather than makign me go through the website?

Additional context

yonzhan commented 2 years ago

@jiasli for awareness

jiasli commented 2 years ago

@paulgmiller, this is a really good suggestion and I also feel multiple copy-paste steps tedious and annoying.

Unfortunately, this message

To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code HCLRV78QY to authenticate.

is returned by AAD's device code flow and we Azure CLI and the underlying MSAL as a client has no control over it. 😥

rayluo commented 2 years ago

To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code AWSDQQ7J6 to authenticate.

I have to copy and paste or retype that code into the brower.

"that message is returned by AAD's device code flow... a client has no control over it."

Well, there was a story behind it. 3 years ago during a hackathon, I used to work out a prototype to bypass the manually copy&paste by some other mechanism, and it felt really cool. But that project was shelved indefinitely, because "signing in via Device Code flow without a chance for user to carefully verify the code" is considered as a phishing risk. Since then, AAD's device code flow also patched the weakness and my workaround no longer works.

Nowadays, Azure CLI's underlying authentication library, MSAL, supports a browser-based "interactive auth".

Currently when I do az login

To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code AWSDQQ7J6 to authenticate.

@paulgmiller, in what scenario you are running the "az login"? Was it run inside a VM that you ssh into?

@jiasli, how does Azure CLI decide whether "az login" would invoke the browser-based interactive auth, or the device code auth? Is it based on browser availability?

@jiasli, @yonzhan, years ago Azure CLI used to support only device code auth, even when running on local desktop. The subsequent introduction of browser-based auth on local desktop was praised as the "improvement of the year". I think we can perhaps bring it to VM, too.

jiasli commented 2 years ago

how does Azure CLI decide whether "az login" would invoke the browser-based interactive auth, or the device code auth? Is it based on browser availability?

The code for deciding whether to use auth code flow is here:

https://github.com/Azure/azure-cli/blob/d331edf76e5866cda1e6e9641d935256fc4f03ff/src/azure-cli-core/azure/cli/core/_profile.py#L148-L150

which calls can_launch_browser:

https://github.com/Azure/azure-cli/blob/07819726e13d72587eb82b65c92ecba3bb009f32/src/azure-cli-core/azure/cli/core/util.py#L725-L748

I think we can perhaps bring it (auth code flow) to VM, too.

If the VM has a GUI, it is already supported. If not, we have to do auth in a local web browser and let AAD send the auth code back to VM, other than http://localhost which I believe is not allowed by first party app configuration.

paulgmiller commented 2 years ago

@rayluo two different headless Linux boxes I ssh into. One where I use vscode to do remote development and another a jumpbox where I need to az login to 2-3 different az resources a day. Both are headless with no gui to speak of but both can port forward

mrburrito commented 1 year ago

Just ran across this issue as we recently switched to using AAD to login to our federated AWS accounts. I'm not sure what "careful verification" I'm supposed to be doing on a randomly generated token. There's plenty of other Microsoft services that allow deeplinked logins. I believe I even found a blog post about how to link various services together using a PowerShell script to generate a QR Code containing the deeplink parameters. It seems like there's no consistency here and what's resulting is a horrible user experience.

If you haven't used AWS' SSO integration with their CLI tool, it's much simpler. If you try to use a command and you're unauthenticated, it auto-opens the browser window, tells you the CLI is attempting to login, and asks you to sign in and authorize the login.

In this case, I would expect the CLI workflow to be similar. If a browser is available, open to the login page with all tokens/ids/etc. already provided and ask me to login and authorize. If the browser isn't available (I also SSH in to a Linux box, so no browser), give me a link that has all the parameters encoded.

Here's the blog where they talk about the kind of deeplink authentication that we're asking for. https://blog.darrenjrobinson.com/azure-ad-and-microsoft-office365-deep-links-and-sign-in-urls/

mrburrito commented 1 year ago

Alternate solution, that I think would be the absolutely ideal workflow:

CLI tool handles all authentication and authorization. It prompts for, and supplies to AAD, the username and password. AAD responds with the authenticator code and pushes that notification to my authenticator app. (or requires me to enter the OTP) Once that workflow is complete, CLI is authenticated and gets credentials.

There are plenty of us that don't have ready access to browsers on the systems we're using, particularly those of us using command line tools.

nielstanghe commented 1 year ago

We use it to pull new images from our container registry. I was thinking about creating a tool to display a QR-code based on the code. Unfortunately, one can not provide the code as a query parameter in the url. Would be a great improvement.

ajtruckle commented 5 months ago

I have a command line tool which is hidden as I am running it in a Windows app behind the scenes. At the moment I display the verification uri in a browser and copy the usercode to the clipboard. The user has to paste it in. I find that if I try to use ?code=xxx that it will not work. @nielstanghe I just found that out.

rayluo commented 5 months ago

@rayluo two different headless Linux boxes I ssh into. One where I use vscode to do remote development and another a jumpbox where I need to az login to 2-3 different az resources a day. Both are headless with no gui to speak of but both can port forward

In ssh scenario, one could create an ssh tunnel for a normal browser login to work, but Azure CLI would also need to add a new az login ... --port 1234 parameter to specify the port. @jiasli you can consider this as a feature request.

microsoft-github-policy-service[bot] commented 5 months ago

Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @adamedx.

jiasli commented 5 months ago

In ssh scenario, one could create an ssh tunnel for a normal browser login to work, but Azure CLI would also need to add a new az login ... --port 1234 parameter to specify the port. @jiasli you can consider this as a feature request.

This is already tracked by https://github.com/Azure/azure-cli/issues/24626.

simongymer commented 16 hours ago

In relation to the original request, this is really annoying for our users who use device code flow login on their devices where we have no keyboard to type because the QR code we create only takes them to the link, it does not fill in the code they are shown. Adding the ability to specify the code in the URL we put in the QR would be useful so they dont have to type in the code manually.

rayluo commented 3 hours ago

In relation to the original request, this is really annoying for our users who use device code flow login on their devices where we have no keyboard to type because the QR code we create only takes them to the link, it does not fill in the code they are shown. Adding the ability to specify the code in the URL we put in the QR would be useful so they dont have to type in the code manually.

Out of curiosity, what kind of device do your users use when they try to complete the device code flow, @simongymer ? It sounds like a new scenario that the device "has no keyboard to type". Device code flow is meant to have the sign-in happen on a capable device.

Also, as a broader response to this thread, my earlier comment still stands. I would suggest @jiasli to close this thread or - even better - convert it to a Q&A in the Github Discussion while choosing my earlier comment as the answer.

mrburrito commented 3 hours ago

@rayluo in regards to your comment about the phishing issues, I wrote a simple wrapper that intercepts the login output with the URL, runs a headless browser in a container, presents the token to the user for confirmation on the command line, and then allows them to login. It's pretty brittle since, if the authentication page changes class names on the elements, my Selenium script will break, but it's been effective for over a year.

There's no reason that couldn't be a native capability for authentication instead of relying on a container running Selenium. The user wouldn't even need to see the URL; they would just be presented with a request to enter their TOTP token or confirm the token sent to their device/Authenticator and then approve the login/access to whatever service is requesting.

My wrapper supports the entire workflow and the user doesn't have to leave their terminal. I think taking that approach and supporting auth via API calls with both the web view and a native callback from the CLI using the same backend to drive the workflow would improve user quality of life and meet the security requirements.