Gerenios / AADInternals

AADInternals PowerShell module for administering Azure AD and Office 365
http://aadinternals.com/aadinternals
MIT License
1.24k stars 214 forks source link

User-Agent based behaviour in AzureAD vs. AADInternals's Get-AADIntAccessTokenForAzureCoreManagement #39

Closed muzso closed 7 months ago

muzso commented 1 year ago

I tried the instructions in the https://o365blog.com/post/quest_for_guest/ blog post with a guest account in one of our tenants.

I used the -UseDeviceCode option for getting an access token, so I executed this: Get-AADIntAccessTokenForAzureCoreManagement -UseDeviceCode -Tenant 6e3846ee-e8ca-4609-a3ab-f405cfbd02cd -SaveToCache

I opened the "https://microsoft.com/devicelogin" URL, entered the displayed user_code and I got the following response:

Help us keep your device secure Your sign-in was successful but your admin requires the device requesting access to be managed by Company Ltd. to access this resource.

I found this very strange, because when I initiated a device authorization grant flow with curl using the very same URL and POST body as used by Get-AccessTokenUsingDeviceCode, I got the expected success message:

Microsoft Office You have signed in to the Microsoft Office application on your device. You may now close this window.

Eventually I've modified my local copy of AADInternals to use a debugging proxy (I prefer the Charles Web Debugging Proxy) with the Invoke-RestMethod calls in the Get-AccessTokenUsingDeviceCode function. As it turned out: the only difference between my successful attempts with curl and the unsuccessful attempts with AADInternals was the User-Agent. :o

The requests from AADInternals (via Windows 10 and PowerShell 5.1) use the following User-Agent: Mozilla/5.0 (Windows NT; Windows NT 10.0; en-US) WindowsPowerShell/5.1.19041.1682

I tested the theory and added the following option to both Invoke-RestMethod calls in Get-AccessTokenUsingDeviceCode: -UserAgent "curl/7.68.0"

With this modification my device authentication flows via Get-AADIntAccessTokenForAzureCoreManagement -UseDeviceCode -Tenant 6e3846ee-e8ca-4609-a3ab-f405cfbd02cd -SaveToCache started to work, i.e. AzureAD gave a success message after I enter the user_code!

I'm not sure what AzureAD tenant configuration is the reason for this behaviour, but the error message that AAD gives here is total BS, since I'm pretty sure that curl is not a device managed by Company Ltd.. :D

P.S.: for the purposes of this GH issue I took the tenant ID and company name from the "Quest for guest access" blog post, but of course I used other values in my own tests. :-)

P.S.2: thanks for AADInternals! It is a great toolkit for investigating AzureAD internals. :-)

muzso commented 1 year ago

Here's a sample screenshot from the error message with the default AADInternals code: Screenshot from 2022-09-26 06-33-00

(Note: I've edited the page by replacing the company name and logo before I took the screenshot :-) )

Here's a sample screenshot from the successful result where a custom (curl) user-agent is used in AADInternals: Screenshot from 2022-09-26 04-27-49

NestoriSyynimaa commented 1 year ago

Thanks for letting me know this! Conditional Access "Device platform" conditions are based on User-Agents, so probably related to that. Have you tried to run it from Cloud Shell or Mac?

muzso commented 1 year ago

Have you tried to run it from Cloud Shell or Mac?

No. I've tried to run AADInternals with the latest PowerShell for Linux, but it didn't work. I've tried the (at the time) latest PowerShell for Windows 10, but it didn't work either. Finally I've settled on the old PowerShell 5.1 (that probably came as a default with Windows 10 itself), because that was the only PS that AADInternals seemed to work with.

NestoriSyynimaa commented 7 months ago

v0.9.x versions should work in other PowerShell versions too.