第100次OAuth2,对不起,但我在这里濒临绝望。我需要将经过身份验证的电子邮件从PowerShell脚本发送到我自己的Exchange Online邮箱(如果这很重要的话,我也是租户管理员)。所以我在AzureAD注册了一个应用程序。
显示名称:
MyApp
支持的帐户类型:
My organization only
应用程序权限:
Microsoft Graph \用户。读取(委派,授予MyDomain)
Office 365 Exchange Online\IMAP。AccessAsApp(应用程序,授予MyDomain)
可能是
Microsoft Graph
此处不需要API。该应用程序有一个秘密,有效期为730天。
我创建了新的Exchange服务主体,并授予了对邮箱的完全访问权限:
$app = Get-AzureADServicePrincipal -SearchString MyApp
New-ServicePrincipal -AppId $app.AppId -ObjectId $app.ObjectId -DisplayName "MyServicePrincipalName"
Add-MailboxPermission -Identity $azureUserName -User $app.ObjectId -AccessRights FullAccess
以下是的结果
Get-MailboxPermission -Identity $azureUserName | fl
:
IsOwner : False
AccessRights : {FullAccess, ReadPermission}
Deny : False
InheritanceType : All
User : NT AUTHORITY\SELF
UserSid : S-X-Y-Z
Identity : admin
IsInherited : False
IsValid : True
ObjectState : Unchanged
IsOwner : False
AccessRights : {FullAccess}
Deny : False
InheritanceType : All
User : MyServicePrincipalName
UserSid : S-X-Y-Z-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxx
Identity : admin
IsInherited : False
IsValid : True
ObjectState : Unchanged
配置此选项后,我尝试将电子邮件添加到收件箱。这是我使用的脚本:
Import-Module AzureAD
Import-Module ExchangeOnlineManagement
$tenantID = "asdf1234"
$appID = "asdf1234"
$secretValue = "asdf1234"
$userName = "[email protected]"
$senderAddress = $userName
$recipientAddress = $userName
$scope = "https://outlook.office365.com/.default"
$tokenURL = "https://login.microsoftonline.com/$tenantID/oauth2/v2.0/token"
# Define the OAuth 2.0 token request body
$tokenRequestBody = @{
client_id = $appID
scope = $scope
client_secret = $secretValue
grant_type = "client_credentials"
}
# Request an access token
$response = Invoke-RestMethod -Uri $tokenURL -Method POST -ContentType "application/x-www-form-urlencoded" -Body $tokenRequestBody
# Access the access token
$accessToken = $response.access_token
# Connect to Office 365 IMAP service
$server = "outlook.office365.com"
$port = 993
$tcpClient = [System.Net.Sockets.TcpClient]::new($server, $port)
$sslStream = [System.Net.Security.SslStream]::new($tcpClient.GetStream())
$sslStream.AuthenticateAsClient($server, $null, [System.Security.Authentication.SslProtocols]::Tls12, $false)
$reader = [System.IO.StreamReader]::new($sslStream)
$writer = [System.IO.StreamWriter]::new($sslStream)
# Read server response
$reader.ReadLine()
# Compose the email
$emailSubject = "Test e-mail"
$emailBody = "This is a test e-mail"
$email = "To: $recipientAddress`nFrom: $senderAddress`nSubject: $emailSubject`n`n$emailBody"
# build XOAUTH2 login string with accesstoken and username
$accessString ="user=" + $userName + "$([char]0x01)auth=Bearer " + $accessToken + "$([char]0x01)$([char]0x01)"
$Bytes = [System.Text.Encoding]::ASCII.GetBytes($accessString)
$loginString = [Convert]::ToBase64String($Bytes)
# Authenticate using XOAUTH2
$command = "A01 AUTHENTICATE XOAUTH2 $loginString"
$writer.WriteLine($command)
# Capture the response
$ResponseStr = $reader.ReadLine()
# Check if the response indicates success
if ($ResponseStr -like "*OK AUTHENTICATE completed.") {
Write-Host "Authentication successful."
} else {
Write-Host "Authentication failed: $ResponseStr"
}
# Send an email
$command = "A01 APPEND INBOX (\Seen) $(" + $email.Length + ")"
$writer.WriteLine($command)
$writer.WriteLine($email)
$writer.WriteLine()
# Logout and clean up sessions
$writer.WriteLine("A01 Logout")
$writer.Close()
$reader.Close()
$sslStream.Close()
$tcpClient.Close()
我得到一个访问令牌
$response
看起来是这样的:
|
标记类型
|
expires_in
|
ext_expires_in
|
access_token
|
|
持票人
|
3599
|
3599
|
myaccesstokenstring
|
但在我执行之后
$writer.WriteLine($command)
,它挂起,几秒钟后我得到错误:
Authentication failed: * BYE Connection is closed. 13
我真的不明白,我做错了什么。也许这对那些知道自己在做什么的人来说是完全愚蠢的。我只是想给自己发送电子邮件通知,我对这里的整个概念的理解非常基本。
非常感谢您的帮助!