Created
June 7, 2021 01:42
-
-
Save gscales/12a4dd21a03c66fa4072b03337ac4fad to your computer and use it in GitHub Desktop.
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
function Get-AccessTokenForGraphFromCertificate{ | |
param( | |
[Parameter(Position = 1, Mandatory = $true)] | |
[String] | |
$TenantDomain, | |
[Parameter(Position = 2, Mandatory = $true)] | |
[String] | |
$ClientId, | |
[Parameter(Position = 3, Mandatory = $false)] | |
[System.Security.Cryptography.X509Certificates.X509Certificate2] | |
$Certificate, | |
[Parameter(Position = 2, Mandatory = $false)] | |
[String] | |
$Scope = "https://graph.microsoft.com/.default" | |
) | |
Process{ | |
# Create base64 hash of certificate | |
$CertificateBase64Hash = [System.Convert]::ToBase64String($Certificate.GetCertHash()) -replace '\+','-' -replace '/','_' -replace '=' | |
# Create Token Timestamps | |
$StartDate = (Get-Date "1970-01-01T00:00:00Z" ).ToUniversalTime() | |
$TokenExpiration = [math]::Round(((New-TimeSpan -Start $StartDate -End (Get-Date).ToUniversalTime().AddMinutes(2)).TotalSeconds),0) | |
$NotBefore = [math]::Round(((New-TimeSpan -Start $StartDate -End ((Get-Date).ToUniversalTime())).TotalSeconds),0) | |
$ClientAssertionheader = @{ | |
alg = "RS256" | |
typ = "JWT" | |
x5t = $CertificateBase64Hash | |
} | |
$ClientAssertionPayLoad = @{ | |
aud = "https://login.microsoftonline.com/$TenantDomain/oauth2/token" | |
exp = $TokenExpiration | |
iss = $ClientId | |
jti = [guid]::NewGuid() | |
nbf = $NotBefore | |
sub = $ClientId | |
} | |
$CAEncodedHeader = [System.Convert]::ToBase64String(([System.Text.Encoding]::UTF8.GetBytes(($ClientAssertionheader | ConvertTo-Json)))) -replace '\+','-' -replace '/','_' -replace '=' | |
$CAEncodedPayload = [System.Convert]::ToBase64String(([System.Text.Encoding]::UTF8.GetBytes(($ClientAssertionPayLoad | ConvertTo-Json)))) -replace '\+','-' -replace '/','_' -replace '=' | |
# Get the private key object of your certificate | |
$PrivateKey = ([System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($Certificate)) | |
$RSAPadding = [Security.Cryptography.RSASignaturePadding]::Pkcs1 | |
$HashAlgorithm = [Security.Cryptography.HashAlgorithmName]::SHA256 | |
# Sign the Assertion | |
$Signature = [Convert]::ToBase64String( | |
$PrivateKey.SignData([System.Text.Encoding]::UTF8.GetBytes(($CAEncodedHeader + "." + $CAEncodedPayload)),$HashAlgorithm,$RSAPadding) | |
) -replace '\+','-' -replace '/','_' -replace '=' | |
# Create the assertion token | |
$ClientAssertion = $CAEncodedHeader + "." + $CAEncodedPayload + "." + $Signature | |
# Create a hash with body parameters | |
$Body = @{ | |
client_id = $ClientId | |
client_assertion = $ClientAssertion | |
client_assertion_type = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer" | |
scope = $Scope | |
grant_type = "client_credentials" | |
} | |
$AuthUrl = "https://login.microsoftonline.com/$TenantDomain/oauth2/v2.0/token" | |
return Invoke-RestMethod -Headers $Header -Method POST -Uri $AuthUrl -Body $Body -ContentType 'application/x-www-form-urlencoded' | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment