如果未授予应用程序权限 full_access_as_app,使用 Oauth 的 Powershell Exchange EWS 脚本身份验证会出现 401 错误
Powershell Exchange EWS script authentication using Oauth getting 401 error if application permission full_access_as_app is not granted
我正在尝试将一些 EWS 脚本转换为使用 oauth。我发现它在 Azure 注册应用程序已获得应用程序权限 full_access_as_app 时有效,但在其仅设置为委派权限时无效 EWS.AccessAsUser.All 。似乎如果给出 full_access_as_app 那么任何拥有 appID 和密码的人都可以访问任何邮箱。当给出 EWS.AccessAsUser.All 时,没有人可以访问任何邮箱。我所希望的是 appID 和秘密本质上是大门的钥匙,但是如果特定用户 运行 脚本或随它传递的凭据(我不知道),那么对邮箱的访问将基于除非它是登录用户,否则不知道该怎么做),具有对邮箱的权限。因此,从本质上讲,您进入了大门,但随后您使用了模拟。应用程序秘密似乎也不能像凭据那样保存在安全的哈希文件中,因此秘密暴露了。感谢您的帮助。
## Request an access token
# Define AppId, secret and scope, your tenant name and endpoint URL
$AppId = 'AppId'
$AppSecret = 'AppSecret'
$Scope = "https://outlook.office365.com/.default"
$TenantName = "domain.onmicrosoft.com"
$Url = "https://login.microsoftonline.com/$TenantName/oauth2/v2.0/token"
# Add System.Web for urlencode
Add-Type -AssemblyName System.Web
# Create body
$Body = @{
client_id = $AppId
client_secret = $AppSecret
scope = $Scope
grant_type = 'client_credentials'
}
# Splat the parameters for Invoke-Restmethod for cleaner code
$PostSplat = @{
ContentType = 'application/x-www-form-urlencoded'
Method = 'POST'
# Create string by joining bodylist with '&'
Body = $Body
Uri = $Url
}
# Request the token!
$Request = Invoke-RestMethod @PostSplat
#######################
$Email = "UserA@domain.com"
# Import "Microsoft Exchange Web Services Managed API 2.2"
Import-Module -Name "C:\Program Files\Microsoft\Exchange\Web Services.2\Microsoft.Exchange.WebServices.dll"
## Create the Exchange Service object with Oauth creds
$Service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService -ArgumentList Exchange2013_SP1
$service.Url= new-object Uri("https://outlook.office365.com/EWS/Exchange.asmx")
$Service.TraceEnabled = $true
$service.ImpersonatedUserId = new-object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress,$Email)
$service.HttpHeaders.Add("X-AnchorMailbox", $Email)
$Service.Credentials = New-Object Microsoft.Exchange.WebServices.Data.OAuthCredentials($Request.access_token)
$OAuthCredentials = New-Object Microsoft.Exchange.WebServices.Data.OAuthCredentials($Request.access_token)
$service.Credentials = $OAuthCredentials
#####################
# WellKnown folders to adjust
$folderNames = "Inbox"
Foreach($folderName in $folderNames)
{
# Set the WellKnownFolder
$FolderId = [Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::$folderName
# Bind to WellKnownFolder Notes
$folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($Service, $folderId)
Write-Host "$($Email): $($folderName): " -NoNewline
$folder.archivetag.RetentionId.Guid
} # Foreach($folderName... END
######################
您应该改为使用 delegated permission。通过委派权限,您将能够以特定用户身份访问 API。
因此,您需要添加EWS.AccessAsUser.All
权限,并获得如下令牌:
## Request an access token
# Define AppId, secret and scope, your tenant name and endpoint URL
$AppId = 'your app id'
$AppSecret = 'your app key'
$Scope = "https://outlook.office365.com/.default"
$TenantName = "{your_tenant}.onmicrosoft.com"
$Url = "https://login.microsoftonline.com/$TenantName/oauth2/v2.0/token"
# Add System.Web for urlencode
Add-Type -AssemblyName System.Web
# Create body
$Body = @{
client_id = $AppId
client_secret = $AppSecret
scope = $Scope
grant_type = 'password'
username = 'your user name here, e.g.,jack@hanxia.onmicrosoft.com'
password = 'your password here ******************'
}
# Splat the parameters for Invoke-Restmethod for cleaner code
$PostSplat = @{
ContentType = 'application/x-www-form-urlencoded'
Method = 'POST'
# Create string by joining bodylist with '&'
Body = $Body
Uri = $Url
}
# Request the token for user!
$Request = Invoke-RestMethod @PostSplat
$Request.access_token
我正在尝试将一些 EWS 脚本转换为使用 oauth。我发现它在 Azure 注册应用程序已获得应用程序权限 full_access_as_app 时有效,但在其仅设置为委派权限时无效 EWS.AccessAsUser.All 。似乎如果给出 full_access_as_app 那么任何拥有 appID 和密码的人都可以访问任何邮箱。当给出 EWS.AccessAsUser.All 时,没有人可以访问任何邮箱。我所希望的是 appID 和秘密本质上是大门的钥匙,但是如果特定用户 运行 脚本或随它传递的凭据(我不知道),那么对邮箱的访问将基于除非它是登录用户,否则不知道该怎么做),具有对邮箱的权限。因此,从本质上讲,您进入了大门,但随后您使用了模拟。应用程序秘密似乎也不能像凭据那样保存在安全的哈希文件中,因此秘密暴露了。感谢您的帮助。
## Request an access token
# Define AppId, secret and scope, your tenant name and endpoint URL
$AppId = 'AppId'
$AppSecret = 'AppSecret'
$Scope = "https://outlook.office365.com/.default"
$TenantName = "domain.onmicrosoft.com"
$Url = "https://login.microsoftonline.com/$TenantName/oauth2/v2.0/token"
# Add System.Web for urlencode
Add-Type -AssemblyName System.Web
# Create body
$Body = @{
client_id = $AppId
client_secret = $AppSecret
scope = $Scope
grant_type = 'client_credentials'
}
# Splat the parameters for Invoke-Restmethod for cleaner code
$PostSplat = @{
ContentType = 'application/x-www-form-urlencoded'
Method = 'POST'
# Create string by joining bodylist with '&'
Body = $Body
Uri = $Url
}
# Request the token!
$Request = Invoke-RestMethod @PostSplat
#######################
$Email = "UserA@domain.com"
# Import "Microsoft Exchange Web Services Managed API 2.2"
Import-Module -Name "C:\Program Files\Microsoft\Exchange\Web Services.2\Microsoft.Exchange.WebServices.dll"
## Create the Exchange Service object with Oauth creds
$Service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService -ArgumentList Exchange2013_SP1
$service.Url= new-object Uri("https://outlook.office365.com/EWS/Exchange.asmx")
$Service.TraceEnabled = $true
$service.ImpersonatedUserId = new-object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress,$Email)
$service.HttpHeaders.Add("X-AnchorMailbox", $Email)
$Service.Credentials = New-Object Microsoft.Exchange.WebServices.Data.OAuthCredentials($Request.access_token)
$OAuthCredentials = New-Object Microsoft.Exchange.WebServices.Data.OAuthCredentials($Request.access_token)
$service.Credentials = $OAuthCredentials
#####################
# WellKnown folders to adjust
$folderNames = "Inbox"
Foreach($folderName in $folderNames)
{
# Set the WellKnownFolder
$FolderId = [Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::$folderName
# Bind to WellKnownFolder Notes
$folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($Service, $folderId)
Write-Host "$($Email): $($folderName): " -NoNewline
$folder.archivetag.RetentionId.Guid
} # Foreach($folderName... END
######################
您应该改为使用 delegated permission。通过委派权限,您将能够以特定用户身份访问 API。
因此,您需要添加EWS.AccessAsUser.All
权限,并获得如下令牌:
## Request an access token
# Define AppId, secret and scope, your tenant name and endpoint URL
$AppId = 'your app id'
$AppSecret = 'your app key'
$Scope = "https://outlook.office365.com/.default"
$TenantName = "{your_tenant}.onmicrosoft.com"
$Url = "https://login.microsoftonline.com/$TenantName/oauth2/v2.0/token"
# Add System.Web for urlencode
Add-Type -AssemblyName System.Web
# Create body
$Body = @{
client_id = $AppId
client_secret = $AppSecret
scope = $Scope
grant_type = 'password'
username = 'your user name here, e.g.,jack@hanxia.onmicrosoft.com'
password = 'your password here ******************'
}
# Splat the parameters for Invoke-Restmethod for cleaner code
$PostSplat = @{
ContentType = 'application/x-www-form-urlencoded'
Method = 'POST'
# Create string by joining bodylist with '&'
Body = $Body
Uri = $Url
}
# Request the token for user!
$Request = Invoke-RestMethod @PostSplat
$Request.access_token