使用Oauth的Powershell Exchange EWS脚本身份验证无法使用保存密码哈希文件

问题描述 投票:0回答:1

通常对于计划内的脚本,我将哈希文件保存到磁盘上,以供脚本使用以下凭据:

$Credential = Get-Credential [email protected] 
$Credential.Password | ConvertFrom-SecureString | Set-Content "C:\admin.pwd" $Username = "[email protected]" 
$Password = Get-Content "C:\admin.pwd" -ErrorAction stop | ConvertTo-SecureString
$Credential = New-Object System.Management.Automation.PSCredential($Username,$Password) 

以下Oath令牌请求可以在正文中以纯文本形式输入password元素的情况下使用,但如果我使用变量$ Credential.Password,则该命令无效。是否有办法使它正常工作,或者以其他方式保护密码?

以下令牌请求生成的错误:

错误:Invoke-RestMethod:{“错误”:“ invalid_grant”,“错误说明”:“ AADSTS50126:由于无效的用户名或密码而导致验证凭据出错...”错误_uri“:” login.microsoftonline.com/error?code = 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 = '[email protected]'
    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

##########

基于来自pip3r的答案的更新脚本(这显然不安全或不建议使用:]

<#
# AppID\Secret hash save to file:
$AppCredential = Get-Credential 'AppIdHere'
$AppCredential.Password | ConvertFrom-SecureString | Set-Content "C:\App.pwd" 

# Admin hash save to file:
$Credential = Get-Credential [email protected]
$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)
$AppSecret = $AppCredential.GetNetworkCredential().Password

$Username = "[email protected]"
$Password = Get-Content "C:\admin.pwd" | ConvertTo-SecureString
$Credential = New-Object System.Management.Automation.PSCredential($Username,$Password)
$Pass = $Credential.GetNetworkCredential().Password


### Request an access token ###

# Define scope, tenant name and endpoint URL

$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

# Create body
$Body = @{
    client_id = $AppId
    client_secret = $AppSecret
    scope = $Scope
    grant_type = 'password'
    username = $Username 
    password = "$Pass"
}

# 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
powershell authentication exchange-server exchangewebservices
1个回答
2
投票

所以...我将提供此作为答案,因为我希望人们理解这是一个示例,该示例将密码存储在具有Get-Credential的文件中(甚至作为密文字符串值)。

@@ mbromb,这将为您提供一种test方式,无论您检索的值是否为正确的值:

在您的$ Credential对象(最后一行)上,运行:$Credential.GetNetworkCredential().Password

这将是您最初使用Get-Credential放入提示中的任何内容的PLAINTEXT值。因此,您可以验证在最初获取它之后,是否将其写入文件,读回并转换为安全字符串对象是否按预期工作。

尝试更简单地解决此问题:如果找到您的'admin.pwd'文件,则从中生成纯文本非常简单。

注意:您可以通过使用ConvertTo / From-SecureString cmdlet的-Key或-SecureKey属性为此加密过程提供受保护的密钥来保护此值。密钥采用字节数组(最好是密码随机的,并具有足够的熵以满足您的需要),SecureKey接受字符串(密码)并根据您的密码生成字节数组。

注意,如果您已经尝试将密码存储到文件中,那么保护存储密码的密码可能不是正确的答案...

© www.soinside.com 2019 - 2024. All rights reserved.