以前に、外部モジュールを利用して、JWT でアクセストークンを取得したことがありました。
しかし、外部モジュールの利用は難しい場合もあるかと思いますので、改めて外部モジュールを使用せずにアクセストークンを取得してみました。
$PRIVATEKEY = "
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCGmAXWxxxxxxxx
...
BEeznnJk+dgA6leOxxxxxxxx
-----END PRIVATE KEY-----
";
$CLIENT_ID = "tO1NYVqXvP86xxxxxxxx";
$CLIENT_SECRET = "7Jxxxxxxxx";
$SERVICE_ACCOUNT = "xxxxx.serviceaccount@yourdomain";
$SCOPE ="bot.message directory"
$GetTokenUrl = "https://auth.worksmobile.com/oauth2/v2.0/token";
$jwt_header = @{
alg = "RS256"
typ = "JWT"
};
$now = Get-Date
$iat_val = [int](Get-Date($now) -UFormat '%s');
$ext_val = [int](Get-Date($now.AddHours(1)) -UFormat '%s');
$jwt_payload = @{
iss = $CLIENT_ID
sub = $SERVICE_ACCOUNT
iat = $iat_val
exp = $ext_val
};
$jwt_str = $jwt_header | ConvertTo-Json -Compress;
$payload_str = $jwt_payload | ConvertTo-Json -Compress;
$base64str = [Convert]::ToBase64String(([System.Text.Encoding]::Default).GetBytes($jwt_str)) `
+ "." `
+ [Convert]::ToBase64String(([System.Text.Encoding]::Default).GetBytes($payload_str));
$base64str = $base64str.Replace('+','-').Replace('/','_').replace('=','');
$bytedata = ([System.Text.Encoding]::Default).GetBytes($base64str);
$rsa = [System.Security.Cryptography.RSA]::Create();
$rsa.ImportFromPem($PRIVATEKEY);
$signature = [Convert]::ToBase64String($rsa.SignData($bytedata, [Security.Cryptography.HashAlgorithmName]::SHA256, [Security.Cryptography.RSASignaturePadding]::Pkcs1)).Replace('+','-').Replace('/','_').replace('=','');
$jwt = "$base64str.$signature";
$requestBody = @{
assertion = $jwt
grant_type = 'urn:ietf:params:oauth:grant-type:jwt-bearer'
client_id = $CLIENT_ID
client_secret = $CLIENT_SECRET
scope = $SCOPE
};
$response = Invoke-RestMethod -Method POST `
-Uri $GetTokenUrl `
-Body $requestBody `
-ContentType 'application/x-www-form-urlencoded'
Write-Host $response.access_token