Last active
November 21, 2018 23:56
-
-
Save darrenjrobinson/1e55df36d9b212bbeede4e163fc3b213 to your computer and use it in GitHub Desktop.
Create Azure Graph API oAuth2.0 PowerShell AuthN/AuthZ Script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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