Create Azure Graph API oAuth2.0 PowerShell AuthN/AuthZ Script
#Sample oAuth 2.0 Microsoft API Powershell AuthN/AuthZ Script | |
# Output Folder for the resultant Script | |
Function Get-Folder($initialDirectory) | |
{ | |
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | |
$foldername = New-Object System.Windows.Forms.FolderBrowserDialog | |
$foldername.rootfolder = "MyComputer" | |
if($foldername.ShowDialog() -eq "OK") | |
{ | |
$folder += $foldername.SelectedPath | |
} | |
return $folder | |
} | |
# Where will we put the script we generate? | |
$WorkingDirectory = Get-Folder | |
write-host "Where would you like the script saved?" | |
$WorkingDirectory[1] | |
$refreshtokenpath = $WorkingDirectory[1]+"\refresh.token" | |
# API Endpoint | |
$resource = "Graph.microsoft.com" | |
# Script Output Filename | |
$scriptname = "Connect-to-Microsoft-$($resource.Split(".")[0]).ps1" | |
$outputscript = "$($WorkingDirectory[1])\$scriptname" | |
$guid = New-Guid | |
$guid.Guid | |
# Get ClientID | |
$msg = "Enter the ClientID/ApplicationID obtained when registering your WebApp (e.g. $($guid.Guid)):" | |
$clientid = Read-Host -Prompt $msg | |
write-host "ClientID/ApplicationID entered is: $clientid" | |
# Get Client Secret | |
$msg = 'Enter the Client Secret obtained when generating your WebApp Key (e.g YXJZo9hup2jQp7sBk/w32PAyBHWAhupx1xU/9urXJRU=):' | |
$clientSecret = Read-Host -Prompt $msg | |
write-host "Client Secret entered is: $clientSecret" | |
# Get Redirect URL | |
$msg = 'Enter the redirect URL configured on your WebApp Key (eg. https://localhost):' | |
$redirectUri = Read-Host -Prompt $msg | |
write-host "Redirect URL entered is: $redirectUri" | |
# Library for encoding URL | |
Add-Type -AssemblyName System.Web | |
# Scope | |
$scope = "User.Read" | |
$strFunctions = @' | |
# Function to popup Auth Dialog Windows Form for getting an AuthCode | |
Function Get-AuthCode { | |
Add-Type -AssemblyName System.Windows.Forms | |
$form = New-Object -TypeName System.Windows.Forms.Form -Property @{Width=440;Height=640} | |
$web = New-Object -TypeName System.Windows.Forms.WebBrowser -Property @{Width=420;Height=600;Url=($url -f ($Scope -join "%20")) } | |
$DocComp = { | |
$Global:uri = $web.Url.AbsoluteUri | |
if ($Global:uri -match "error=[^&]*|code=[^&]*") {$form.Close() } | |
} | |
$web.ScriptErrorsSuppressed = $true | |
$web.Add_DocumentCompleted($DocComp) | |
$form.Controls.Add($web) | |
$form.Add_Shown({$form.Activate()}) | |
$form.ShowDialog() | Out-Null | |
$queryOutput = [System.Web.HttpUtility]::ParseQueryString($web.Url.Query) | |
$output = @{} | |
foreach($key in $queryOutput.Keys){ | |
$output["$key"] = $queryOutput[$key] | |
} | |
$output | |
} | |
function Get-AzureAuthN ($resource) { | |
# Get Permissions (if the first time, get an AuthCode and Get a Bearer and Refresh Token | |
# Get AuthCode | |
$url = "https://login.microsoftonline.com/common/oauth2/authorize?response_type=code&redirect_uri=$redirectUri&client_id=$clientID&resource=$resourceEncoded&scope=$scopeEncoded" | |
Get-AuthCode | |
# Extract Access token from the returned URI | |
$regex = '(?<=code=)(.*)(?=&)' | |
#if ($uri){ | |
$authCode = ($uri | Select-string -pattern $regex).Matches[0].Value | |
Write-output "Received an authCode, $authCode" | |
#get Access Token | |
$body = "grant_type=authorization_code&redirect_uri=$redirectUri&client_id=$clientId&client_secret=$clientSecretEncoded&code=$authCode&resource=$resource" | |
$Authorization = Invoke-RestMethod https://login.microsoftonline.com/common/oauth2/token ` | |
-Method Post -ContentType "application/x-www-form-urlencoded" ` | |
-Body $body ` | |
-ErrorAction STOP | |
Write-output $Authorization.access_token | |
$Global:accesstoken = $Authorization.access_token | |
$Global:refreshtoken = $Authorization.refresh_token | |
if ($refreshtoken){$refreshtoken |out-file "$($refreshtokenpath)"} | |
# Test API Call to get Current User | |
$queryURL = "https://graph.microsoft.com/v1.0/me" | |
if ($Authorization.token_type -eq "Bearer" ){ | |
Write-Host "You've successfully authenticated to $($resource) with authorization for $($Authorization.scope)" | |
Write-Host "Test Query for authenticated user" | |
# Test Query | |
# Get the user who authenticated using this script | |
$currentUser = Invoke-RestMethod -Method Get -Headers @{Authorization = "Bearer $accesstoken" | |
'Content-Type' = 'application/json'} ` | |
-Uri $queryURL | |
if ($currentUser) {$currentUser} else {"That's weird, the query failed. Check the error message."} | |
} | |
else{ | |
write-host "Check the console for errors. Chances are you provided the incorrect clientID and clientSecret combination for the API Endpoint selected" | |
} | |
} | |
function Get-NewTokens { | |
# We have a previous refresh token. | |
# use it to get a new token | |
$refreshtoken = Get-Content "$($refreshtokenpath)" | |
# Refresh the token | |
#get Access Token | |
$body = "grant_type=refresh_token&refresh_token=$refreshtoken&redirect_uri=$redirectUri&client_id=$clientId&client_secret=$clientSecretEncoded" | |
$Global:Authorization = Invoke-RestMethod https://login.microsoftonline.com/common/oauth2/token ` | |
-Method Post -ContentType "application/x-www-form-urlencoded" ` | |
-Body $body ` | |
-ErrorAction STOP | |
$Global:accesstoken = $Authorization.access_token | |
$Global:refreshtoken = $Authorization.refresh_token | |
if ($refreshtoken){ | |
$refreshtoken | out-file "$($refreshtokenpath)" | |
write-host "Updated tokens" | |
$Authorization | |
} | |
} | |
'@ | |
# Create Output Script | |
$OutputFile = New-Item -Path $outputscript -ItemType File -Force | |
Write-Output "#Sample oAuth 2.0 Microsoft API Powershell AuthN/AuthZ Script" | Out-File $OutputFile -Append | |
Write-Output "#The resource URI" | Out-File $OutputFile -Append | |
Write-Output "`$resource = ""https://$($resource.ToLower())""" | Out-File $OutputFile -Append | |
Write-Output "#Your Client ID and Client Secret obainted when registering your WebApp" | Out-File $OutputFile -Append | |
Write-Output "`$clientid = ""$($clientid)""" | Out-File $OutputFile -Append | |
Write-Output "`$clientSecret = ""$($clientSecret)""" | Out-File $OutputFile -Append | |
Write-Output "#Your Reply URL configured when registering your WebApp" | Out-File $OutputFile -Append | |
Write-Output "`$redirectUri = ""$($redirectUri)""" | Out-File $OutputFile -Append | |
Write-Output "#Scope" | Out-File $OutputFile -Append | |
Write-Output '$scope = "User.Read"' | Out-File $OutputFile -Append | |
Write-Output 'Add-Type -AssemblyName System.Web' | Out-File $OutputFile -Append | |
Write-Output "#UrlEncode the ClientID and ClientSecret and URL's for special characters" | Out-File $OutputFile -Append | |
Write-Output "`$clientIDEncoded = [System.Web.HttpUtility]::UrlEncode($('$clientid')`)" | Out-File $OutputFile -Append | |
Write-Output "`$clientSecretEncoded = [System.Web.HttpUtility]::UrlEncode($('$clientSecret')`)" | Out-File $OutputFile -Append | |
Write-Output "`$resourceEncoded = [System.Web.HttpUtility]::UrlEncode($('$resource')`)" | Out-File $OutputFile -Append | |
Write-Output "`$scopeEncoded = [System.Web.HttpUtility]::UrlEncode($('$scope')`)" | Out-File $OutputFile -Append | |
Write-Output "#Refresh Token Path" | Out-File $OutputFile -Append | |
Write-Output "`$refreshtokenpath = ""$($refreshtokenpath)""" | Out-File $OutputFile -Append | |
Write-Output "#Functions" | Out-File $OutputFile -Append | |
Write-Output $strFunctions | Out-File $OutputFile -Append | |
Write-Output "#AuthN" | Out-File $OutputFile -Append | |
Write-Output 'Get-AzureAuthN ($resource)' | Out-File $OutputFile -Append | |
Write-Output "#Test Refreshing our token" | Out-File $OutputFile -Append | |
Write-Output 'Get-NewTokens' | Out-File $OutputFile -Append | |
# Execute the script | |
Invoke-Expression "$OutputFile" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment