private/get-AccessToken.ps1
function get-AccessToken{ <# Author = "Jos Lieben (jos@lieben.nu)" CompanyName = "Lieben Consultancy" Copyright = "https://www.lieben.nu/liebensraum/commercial-use/" #> Param( [Parameter(Mandatory=$true)]$resource, [Switch]$returnHeader ) if($global:octo.connection -eq "Pending"){ Throw "Failed to determine authentication mode, please run connect-M365 first!" } if(!$global:octo.LCRefreshToken){ if($global:octo.userConfig.authMode -eq "Delegated"){ try{ $global:octo.LCRefreshToken = get-AuthorizationCode -clientId $global:octo.userConfig.LCClientId }catch{ Write-Error $_ -ErrorAction Continue Write-Error "Failed to authorize, trying again by forcing reconsent...." -ErrorAction Continue $global:octo.LCRefreshToken = get-AuthorizationCode -clientId $global:octo.userConfig.LCClientId -reConsent } } } if(!$global:octo.LCCachedTokens.$resource){ $global:octo.LCCachedTokens.$resource = @{ "validFrom" = Get-Date "accessToken" = $Null } } if(!$global:octo.LCCachedTokens.$($resource).accessToken -or $global:octo.LCCachedTokens.$($resource).validFrom -lt (Get-Date).AddMinutes(-15)){ Write-LogMessage -level 5 -message "Token cache miss, refreshing $($global:octo.userConfig.authMode) V1 token for $resource..." if($global:octo.userConfig.authMode -eq "ServicePrincipal"){ $assertion = Get-Assertion $response = (Invoke-RestMethod "$($global:octo.idpUrl)/$($global:octo.userConfig.LCTenantId)/oauth2/token" -Method POST -Body "resource=$([System.Web.HttpUtility]::UrlEncode($resource))&grant_type=client_credentials&client_id=$([System.Web.HttpUtility]::UrlEncode($global:octo.userConfig.LCClientId))&client_assertion=$([System.Web.HttpUtility]::UrlEncode($assertion))&client_assertion_type=$([System.Web.HttpUtility]::UrlEncode('urn:ietf:params:oauth:client-assertion-type:jwt-bearer'))" -ErrorAction Stop -Verbose:$false) }elseif($global:octo.userConfig.authMode -eq "ManagedIdentity"){ $endpoint = "$($env:IDENTITY_ENDPOINT)?resource=$($resource)" $response = Invoke-RestMethod -Uri $endpoint -Headers @{"X-IDENTITY-HEADER"=$env:IDENTITY_HEADER;Metadata="true"} -Method GET }else{ $response = (Invoke-RestMethod "$($global:octo.idpUrl)/common/oauth2/token" -Method POST -Body "resource=$([System.Web.HttpUtility]::UrlEncode($resource))&grant_type=refresh_token&refresh_token=$($global:octo.LCRefreshToken)&client_id=$($global:octo.userConfig.LCClientId)&scope=openid" -ErrorAction Stop -Verbose:$false) } if($response.access_token){ if($response.refresh_token){ Write-LogMessage -level 5 -message "Refresh token received, stored in cache" $global:octo.LCRefreshToken = $response.refresh_token } Write-LogMessage -level 5 -message "Access token valid from $((Get-Date).ToString()), stored in cache" $global:octo.LCCachedTokens.$($resource).accessToken = $response.access_token $global:octo.LCCachedTokens.$($resource).validFrom = Get-Date if($global:octo.userConfig.authMode -ne "Delegated"){ #see if we can get a client ID from the token try{ Write-LogMessage -level 5 -message "Parsing client ID from token..." $global:octo.autDetectedClientId = ([System.Text.Encoding]::UTF8.GetString([convert]::FromBase64String(($response.access_token.Split(".")[1].Replace('-','+').Replace('_','/') + '===').Substring(0, 4 * [math]::Ceiling(($response.access_token.Split(".")[1].Length) / 4)))) | convertfrom-json).appid Write-LogMessage -level 5 -message "Client ID detected: $($global:octo.autDetectedClientId)" }catch{$Null} } }else{ Write-Error $_ -ErrorAction Continue Write-Error "Failed to retrieve access and/or refresh token! Please retry and/or report the previous error." -ErrorAction Stop } } if($returnHeader){ return [Hashtable]@{"Authorization" = "Bearer $($global:octo.LCCachedTokens.$($resource).accessToken)"} }else{ return $global:octo.LCCachedTokens.$($resource).accessToken } } |