Came across this post and wanted to bookmark it for myself. Has three ways of getting Access Tokens without any App Registrations.
The first option is a great, I wasn’t aware of it! So simple.
For the second option I use PowerShell. So Get-AzAccessToken
it is for me.
Another option I found is to use the Graph PowerShell service principal that gets registered if you have used the Graph cmdlets. It gets installed the first time the cmdlets are used to connect. It’s appId is “14d82eec-204b-4c2f-b7e8-296a70dab67e” so using a function I wrote as part of a previous post I can do the following to get a token:
1 |
Get-MSDeviceToken -TenantId $tenantId -AppId $appId -Scope openid |
This is the function for completeness:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
function Get-MSDeviceToken { param( [Parameter(Mandatory=$true)] [string]$TenantId, [Parameter(Mandatory=$true)] [Alias("ClientId")] [string]$AppId, [Parameter(Mandatory=$true)] [string]$Scope ) $authUrl = "https://login.microsoftonline.com/$tenantId" # From https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-device-code # Device authorization request $authBody = @{ "tenant" = "$TenantId"; "client_id" = "$AppId"; "scope" = $Scope } $response = Invoke-RestMethod -Method POST -Uri "$authUrl/oauth2/v2.0/devicecode" -Body $authBody Write-Host $response.Message Set-Clipboard -Value $response.user_code $expiresMins = $response.expires_in / 60 Write-Host "The code is copied to your clipboard for ease of use. It expires in $expiresMins minutes." $waitInterval = $response.interval # Authenticating the user $authBody2 = @{ "tenant" = "$tenantId"; "grant_type" = "urn:ietf:params:oauth:grant-type:device_code"; "client_id" = "$appId"; "device_code" = $response.device_code } $authStatus = "waiting" $response2 = $null while ($authStatus -eq "waiting") { # Try to get the access token. if we encounter an error check the reason. # If the reason is we are waiting then sleep for some time. # If the reason is the user has declined or we timed out then quit. try { $response2 = Invoke-RestMethod -Method POST -Uri "$authUrl/oauth2/v2.0/token" -Body $authBody2 } catch { switch (($Error[0].ErrorDetails.Message | ConvertFrom-Json).error) { "authorization_pending" { Write-Host "Waiting $waitInterval seconds for browser authentication to complete." Start-Sleep -Seconds $waitInterval } "authorization_declined" { # Note to self: this does not work if I decline in the browser. Not sure what use-case this is supposed to capture. Write-Host "Quitting as authorization was declined in browser." $authStatus = "failed" } "expired_token" { Write-Host "Authentication timed out." $authStatus = "failed" } } } if ($null -ne $response2) { $authStatus = "success" } } if ($authStatus -eq "failed") { $null } else { $response2 } } |
Update (4th Nov 2024): Came across this post today. Adding a note here for my reference:
1 2 3 4 5 |
Install-Module Microsoft.Graph -scope CurrentUser Install-Module Az -scope CurrentUser Connect-azAccount -Tenant %TenantIDhere% $token = Get-azAccessToken -ResourceTypeName MSGraph $SecureToken = ConvertTo-SecureString $token.token -AsPlainText -Force |
Key thing is you can user Connect-AzAccount
to request tokens for other services. I was aware of that, but thought it was limited to Azure items such as Key Vaults etc.