在New-WebServiceProxy中包含德语umlauts的PSCredential

5

我尝试创建一个包含德语变音符号的密码的PSCredential对象,并将其传递给New-WebServiceProxy cmdlet。只要密码不包含任何变音符号,代码就按预期工作,例如以下示例:

$secp = ConvertTo-SecureString 'abÜ312!' -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential('\user@db', $secp)
$proxy = New-WebServiceProxy -Uri "https://example.com/webservice/myWs?wsdl" -Credential $mycreds

在这种情况下,我收到以下错误信息:

New-WebServiceProxy:请求失败,HTTP状态为401:未经授权。

当我使用例如Fiddler捕获流量时,我看到New-WebServiceProxy cmdlet正在添加凭据作为基本授权,并使用base64编码:
GET https://example.com/webservice/myWs?wsdl HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 4.0.30319.42000)
Authorization: Basic dXNlckBkYjphYtwzMTIh
Host: example.com

这是解码后的Base64字符串在Utf8中的样子:

String in UTF8

看起来 PowerShell 将 Umlauts 编码为 ANSI 字符串。 当我手动对凭据进行 base64 编码时(使用 dXNlckBkYjphYsOcMzEyIQ== 而不是 dXNlckBkYjphYtwzMTIh),并回复 Fiddler 请求,我得到了预期的响应。
不幸的是,我无法使用此解决方法,因为 New-WebServiceProxy 不允许我自己添加授权标头。
有任何想法吗?

1
那太糟糕了。除了避免使用非ASCII字符的用户名和密码外,按照此答案所述将整个系统切换到UTF-8可能会起作用,但即使如此,也会产生深远的影响。 - mklement0
2
难以置信,现在已经是2021年了,我们仍然需要处理这样的问题。从快速查看源代码来看,似乎是“WebRequest”类的实现细节,或者说是.NET的实现细节,因此我脑海中没有解决方案,除非不使用umlauts,或者使用其他工具构建代理。 - marsze
1
我同意你的看法,@marsze。很难相信我们现在仍然不得不处理这样的问题。 - Martin Brandl
2
@MartinBrandl: 希望如此-至少找出解决方法是否有帮助。一些背景信息(绝对不是我的专业领域):New-WebServiceProxy在PowerShell(Core)中已不再可用,但奇怪的是它仍然是源代码的一部分:https://github.com/PowerShell/PowerShell/blob/master/src/Microsoft.PowerShell.Commands.Management/commands/management/WebServiceProxy.cs。 GitHub问题及讨论:https://github.com/PowerShell/PowerShell/issues/9838 - mklement0
2个回答

2
这段文字的意思是:链接 mklement0的答案帮助我找到了解决方案:
脚本是使用PowerShell ISE编写和保存的。我刚刚意识到ISE使用带BOM的UTF-8编码保存文件。如果我将编码更改为UTF-8,一切都可以正常工作。
以下是一个简短的脚本,用于将文件的编码更改为UTF-8:
$scriptPath = "c:/path/to/script.ps1"
$content = Get-Content -Raw $scriptPath
[System.IO.File]::WriteAllLines($scriptPath, $content, (New-Object System.Text.UTF8Encoding))

2
有趣。只是为了我理解:这是一种依赖于故意让Windows PowerShell将您的UTF-8编码脚本误解为ANSI编码的_变通方法_,对吗? - mklement0
1
@mklement0 是的,从我的测试结果来看,似乎正是这样。这背后的想法并不全是坏的,我将其作为我的答案方法的基础。 - marsze

2
有趣。你的解决方法启发了我想到了这个更通用的解决方法,它不依赖于保存错误编码的脚本文件。相反,它只会错误地编码密码字符串。
如果这个方法可行,请告诉我。
$pw = 'abÜ312!'
# incorrectly encode the UTF8-bytes as ANSI (this yields abÜ312!)
$dummy = [Text.Encoding]::Default.GetString([Text.Encoding]::UTF8.GetBytes($pw))
$secp = ConvertTo-SecureString $dummy -AsPlainText -Force

我认为这种方法对于所有字符都不起作用,但是我对编码的了解还不足以确定。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接