【发布时间】:2020-07-04 06:18:46
【问题描述】:
通常对于计划脚本,我将哈希文件保存到磁盘,以便脚本使用如下凭据:
$Credential = Get-Credential Admin@domain.com
$Credential.Password | ConvertFrom-SecureString | Set-Content "C:\admin.pwd" $Username = "Admin@domain.com"
$Password = Get-Content "C:\admin.pwd" -ErrorAction stop | ConvertTo-SecureString
$Credential = New-Object System.Management.Automation.PSCredential($Username,$Password)
如果正文中的密码元素以纯文本形式输入,则以下 Oath 令牌请求有效,但如果我使用变量 $Credential.Password 则无效。有没有办法让它工作,或者以其他方式保护密码?
以下令牌请求产生的错误:
错误:Invoke-RestMethod : {"error":"invalid_grant","error_description":"AADSTS50126: 由于用户名或密码无效,验证凭据时出错..."error_uri":"login.microsoftonline.com/error?代码=50126"}
## Request an access token
# Define AppId, secret and scope, your tenant name and endpoint URL
$AppId = 'AppIdHere'
$AppSecret = 'AppSecretHere'
$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 = 'password'
username = 'Admin@domain.com'
password = $Credential.Password
}
# 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
##########
============================
根据 thepip3r 的回答和 Microsoft 支持更新了脚本:
密码和秘密在网络上以纯文本形式传递,但不是 暴露在脚本中,并有一定程度的安全性保存为哈希 文件
调整为不将密码或秘密保存到变量中 提高安全性免受可以访问内存的攻击(MS 推荐支持)
为 Azure 注册应用程序使用证书而不是使用证书的选项 一个 App Secret,以提高网络的安全性
另一种选择是使用“Azure 自动化”,它允许 从 O365 中运行脚本,这应该更安全。 另一种可能的替代方案可能是 Azure Functions。
# One time AppID\Secret hash save to file:
## $AppCredential = Get-Credential 'AppIdHere'
## $AppCredential.Password | ConvertFrom-SecureString | Set-Content "C:\App.pwd"
# One time Admin hash save to file:
## $Credential = Get-Credential admin@domain.com
## $Credential.Password | ConvertFrom-SecureString | Set-Content "C:\admin.pwd"
$AppId = 'AppIdHere'
$AppS = Get-Content "C:\App.pwd" | ConvertTo-SecureString
$AppCredential = New-Object System.Management.Automation.PSCredential($AppId,$AppS)
$Username = "admin@domain.com"
$Password = Get-Content "C:\admin.pwd" | ConvertTo-SecureString
$Credential = New-Object System.Management.Automation.PSCredential($Username,$Password)
### Request an access token ###
$Scope = "https://outlook.office365.com/.default"
$TenantName = "usablelife.onmicrosoft.com"
$Url = "https://login.microsoftonline.com/$TenantName/oauth2/v2.0/token"
# Add System.Web for urlencode
Add-Type -AssemblyName System.Web
# Request the token!
$Request = Invoke-RestMethod -Body @{
client_id = $AppId
client_secret = $AppCredential.GetNetworkCredential().Password
scope = $Scope
grant_type = 'password'
username = $Username
password = $Credential.GetNetworkCredential().Password
} `
-ContentType 'application/x-www-form-urlencoded' `
-Method 'POST' `
-Uri "https://login.microsoftonline.com/$TenantName/oauth2/v2.0/token"
【问题讨论】:
标签: powershell authentication exchange-server exchangewebservices