Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save darrenjrobinson/1e55df36d9b212bbeede4e163fc3b213 to your computer and use it in GitHub Desktop.
Save darrenjrobinson/1e55df36d9b212bbeede4e163fc3b213 to your computer and use it in GitHub Desktop.
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