3

以下のコードを使用して、保護された HTTP ソースからファイルをダウンロードしようとすると、401 Unauthorized が返されます。

$pfile = "\\some\local\leaf\path"
$user = "MyUserName"

$pwdIn = read-host -assecurestring | convertfrom-securestring | out-file $pfile
$pwdOut = get-content $pFile| convertto-securestring

$url="http://path.to/file"
$file = "\\localpath\to\file"
$webclient = new-object System.Net.WebClient
$webclient.Credentials = new-object System.Net.NetworkCredential($user, $pwdOut)
$webclient.DownloadFile($url,$file)

次のようにパスワードファイルを書き込むステップをスキップすることも同様です。

$pwd = read-host -assecurestring 
...
$webclient.Credentials = new-object System.Net.NetworkCredential($user, $pwd)

ただし、セキュアストリングの作成をスキップしても問題なく機能します。

 $pwd = read-host
 ...
 $webclient.Credentials = new-object System.Net.NetworkCredential($user, $pwd)

上記のコードは、他のエラーを返しません。上部の元のコード バージョンをテストしたときに、ターゲット パスワード ファイルの存在と見かけの構造的妥当性を確認しました。コード全体が 1 つのスクリプト内にあるため、convertto と convertfrom の実行中の環境は同じです。これを x86 と 64 ビットの両方の powershell で試しました。

実際、安全な文字列を正しい基本文字列に戻し、WebClient で使用することもできます。

$pwdtmp = get-content $pFile| convertto-securestring
$pwdOut = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($pwdtmp))
$webclient.Credentials = new-object System.Net.NetworkCredential($user, $pwdOut)

したがって、問題は System.Net.NetworkCredential クラスで SecureString を使用することにあるはずですが、http://msdn.microsoft.com/en-us/library/system.net.networkcredential.aspx、および私が見つけたいくつかの例だけですSecureString が 2 番目の引数として機能することを示します。

この投稿を書いているときに、実際に解決策を見つけました。

$user = "user"
$pwd = read-host -assecurestring
$creds = New-Object System.Management.Automation.PSCredential `
     -ArgumentList $user, $pwd  
$webclient.Credentials = new-object System.Net.NetworkCredential($user, $Creds.GetNetworkCredential().Password)
$webclient.DownloadFile($url,$file)

しかし、PSCredential.Password が動作するのに SecureString 型が動作しない理由についての説明ではありません。$creds|gm を実行すると、$creds.Password が実際には SecureString でもあることが明確に示されます。

TypeName: System.Management.Automation.PSCredential

名前 MemberType 定義

---- ---------- ---------- Equals メソッド bool Equals(System.Object obj)
GetHashCode メソッド int GetHashCode()
GetNetworkCredential メソッド System.Net.NetworkCredential GetNetworkCredential() GetType メソッドの型 GetType() ToString メソッドの文字列 ToString()
Password プロパティ System.Security.SecureString Password {get;}

何を与える?

4

1 に答える 1

7

おそらく、以前のバージョンの .Net Framework の System.Net.NetworkCredential を使用しています。SecureString を受け入れるコンストラクターのオーバーロードは、.Net 4.0 で導入されました。文字列を受け入れるコンストラクターに SecureString を渡すと、powershell は SecureString を文字列に変換し、文字列 "System.Security.SecureString" の値をレンダリングします。いくつかのことをテストできます。

  1. コンストラクターを呼び出し、そのパスワード プロパティを表示して値を確認します。私の仮定が正しければ、「System.Security.SecureString」になります。

  2. 使用している .Net Framework のバージョンを確認します。

    $PSVersionTable.CLRVersion

  3. オブジェクトにクエリを実行して、オブジェクトに含まれるコンストラクターを確認します。

    を。Jeffrey Snover からこの関数をコピーして貼り付けます。

    b. 関数を呼び出します。

    get コンストラクター system.net.networkcredential

以下の出力からわかるように (私は .net 2.0 を使用しています)、SecureString を受け入れるオーバーロードはありません。

NetworkCredential(
)
NetworkCredential(
    String userName,
    String password,
)
NetworkCredential(
    String userName,
    String password,
    String domain,
)
于 2012-10-16T20:07:19.580 に答える