Stack Overflow Asked on December 23, 2021
I wrote the below function to pop up an IE window to handle the user authentication of the OAuth2.0 authorization code flow in PowerShell which works but when calling it as a function, it doesn’t stay in the while loop to wait for the URL of the IE window to change and to filter out the OAuth2.0 authorization code and then close the window.
Is there a way to keep the function "open" for longer and to make sure it waits for the URL of the IE window to change?
All remarks regarding the function are welcome…
function Show-OAuth2AuthCodeWindow {
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true, Position = 0, HelpMessage = "The OAuth2 authorization code URL pointing towards the oauth2/v2.0/authorize endpoint as documented here: https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow")]
[System.Uri] $URL
)
try {
# create an Internet Explorer object to display the OAuth 2 authorization code browser window to authenticate
$InternetExplorer = New-Object -ComObject InternetExplorer.Application
$InternetExplorer.Width = "600"
$InternetExplorer.Height = "500"
$InternetExplorer.AddressBar = $false # disable the address bar
$InternetExplorer.ToolBar = $false # disable the tool bar
$InternetExplorer.StatusBar = $false # disable the status bar
# store the Console Window Handle (HWND) of the created Internet Explorer object
$InternetExplorerHWND = $InternetExplorer.HWND
# make the browser window visible and navigate to the OAuth2 authorization code URL supplied in the $URL parameter
$InternetExplorer.Navigate($URL)
# give Internet Explorer some time to start up
Start-Sleep -Seconds 1
# get the Internet Explorer window as application object
$InternetExplorerWindow = (New-Object -ComObject Shell.Application).Windows() | Where-Object {($_.LocationURL -match "(^https?://.+)") -and ($_.HWND -eq $InternetExplorerHWND)}
# wait for the URL of the Internet Explorer window to hold the OAuth2 authorization code after a successful authentication and close the window
while (($InternetExplorerWindow = (New-Object -ComObject Shell.Application).Windows() | Where-Object {($_.LocationURL -match "(^https?://.+)") -and ($_.HWND -eq $InternetExplorerHWND)})) {
Write-Host $InternetExplorerWindow.LocationURL
if (($InternetExplorerWindow.LocationURL).StartsWith($RedirectURI.ToString() + "?code=")) {
$OAuth2AuthCode = $InternetExplorerWindow.LocationURL
$OAuth2AuthCode = $OAuth2AuthCode -replace (".*code=") -replace ("&.*")
$InternetExplorerWindow.Quit()
}
}
# return the OAuth2 Authorization Code
return $OAuth2AuthCode
}
catch {
Write-Host -ForegroundColor Red "Could not create a browser window for the OAuth2 authentication"
}
}
Answer from this blog post
I managed to get the Auth code flow working using the headless chrome. All you need are these two components.
Once you have these setup, you need to use the below Powershell commands to generate token using Auth code flow
$SeleniumWebDriverFullPath = ".WebDriver.dll" # Full path to selenium web driver
$ClientId = ""
$Scopes = ""
$RedirectUri = ""
$authCodeUri = "$($AuthorizeEndpoint.TrimEnd("/"))?client_id=$ClientId&scope=$Scopes&redirect_uri=$RedirectUri&response_type=code
Write-Host $authCodeUri
Import-Module $SeleniumWebDriverFullPath
$ChromeOptions = New-Object OpenQA.Selenium.Edge.EdgeOptions
$ChromeOptions.AddArgument('headless')
$ChromeOptions.AcceptInsecureCertificates = $True
$ChromeDriver = New-Object OpenQA.Selenium.Edge.EdgeDriver($ChromeOptions);
$ChromeDriver.Navigate().GoToUrl($authCodeUri);
while (!$ChromeDriver.Url.Contains("code")) { Start-Sleep 1 }
Write-Host $ChromeDriver.Url
$ParsedQueryString = [System.Web.HttpUtility]::ParseQueryString($ChromeDriver.Url)
$Code = $ParsedQueryString[0]
Write-Host "Received code: $Code"
Write-Host "Exchanging code for a token"
$tokenrequest = @{ "client_id" = $ClientId; "grant_type" = "authorization_code"; "redirect_uri" = $RedirectUri; "code" = $ParsedQueryString[0] }
$token = Invoke-RestMethod -Method Post -Uri $AuthTokenEndpoint -Body $tokenrequest
$tokenString = $token | ConvertTo-Json
Answered by Sachin on December 23, 2021
The following example does what you want with a WebBrowser control, which allows you to register a Navigating event handler to catch the authorization code obtained from your authorization server.
Answered by Bill Lam on December 23, 2021
My guess is that the function has no idea what $RedirectURI
is.
You should make that a second parameter to the function or it should be (at least) Script scoped
I'd prefer using a second parameter, but if you do scoping, you should be able to use it inside the function with $script:RedirectURI
Answered by Theo on December 23, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP