

＃同じ質問をわんくま同盟でも同じ質問をさせていただいております。

現在Windows10Mobileを利用したアプリを開発中です。  
Windows10MobileアプリではHttpClientクラスを利用する必要があると認識しており、  
環境の構成上、Digest認証後にPOSTリクエストを送信する必要があります。

いくらかプログラムしてみましたがエラーとなっています。  
HTTPの内容を確認したところHTTPヘッダの「Content-Length」は正しく設定されていますが、  
肝心のHTTPボディにPOSTパラメータが設定されていません。

以下にサンプルコードを記載させていただきますが、何か不備等はございませんでしょうか。  
お分かりになる範囲でご教授いただければ幸いです。

[code]

    Imports System.Net
    Imports System.Net.Http
    
    Public Class Class1
     Public Async Function registOrderInfo() As Task(Of String)
    
     Dim url As Uri = New Uri("http://test.com/test/testGet.cgi")
     Dim sysHandler As HttpClientHandler = New HttpClientHandler()
     sysHandler.Credentials = New NetworkCredential("testuser", "testpass") 'Digest認証用アカウント
    Dim client As HttpClient = New HttpClient(sysHandler)
    
     Try
     Dim param As List(Of KeyValuePair(Of String, String)) = New List(Of KeyValuePair(Of String, String))
     param.Add(New KeyValuePair(Of String, String)("test1", "aaa"))
     param.Add(New KeyValuePair(Of String, String)("test2", "bbb"))
    
     Dim content As HttpContent = New FormUrlEncodedContent(param)
     Dim response As HttpResponseMessage = Await client.PostAsync(url, content)
    
     Dim statusCode As HttpResponseMessage = response.EnsureSuccessStatusCode()
     Dim message As String = Await response.Content.ReadAsStringAsync()
     Catch ex As Exception
     httpResponseBody = "Error: " + ex.HResult.ToString("X") + " Message: " + ex.Message
     End Try
    
     Return ""
     End Function
    
    End Class
    
[/code]

（1月11日追記）  
今更ながら気がついて大変申し訳ございませんが、  
今回Digest認証を実施している関係上、2回アクセスします。

1回目は当然、401で返ってくるのですが、その1回目のhttpRequestのBodyにはPOSTパラメータが設定されていますが、2回目のhttpRequestのBodyが空でRequestされていました。

1回目と2回目のアクセスはPostAsyncの中で実行されていると理解していますが、  
本事象を解決する方法はありませんでしょうか。


CC BY-SA 3.0
2017-01-10T09:33:41.247
31746
2017-11-07T10:05:03.827
2017-01-11T13:18:21.310
20162
20162
question
windows .net
Digest認証ありのPOSTリクエストにおいて、HTTPボディが空になる


`HttpClientHandler`の`PreAuthenticate`プロパティを指定する必要があるのでは。

[code]

    sysHandler.PreAuthenticate = True
    
[/code]


CC BY-SA 3.0
2017-01-11T13:14:03.963
31777
2017-01-11T13:14:03.963
5750
31746
answer


>
> 1回目は当然、401で返ってくるのですが、その1回目のhttpRequestのBodyにはPOSTパラメータが設定されていますが、2回目のhttpRequestのBodyが空でRequestされていました。
>
> 1回目と2回目のアクセスはPostAsyncの中で実行されていると理解していますが、  
>  本事象を解決する方法はありませんでしょうか。

認証を要求される場面で、未認証状態のままデータを`POST`すべきではありません。理由としては

  * 認証が通るとは限らない
  * その状態で`POST`データを送り込むのはサーバーからみてDoS攻撃になりかねない
  * クライアントからみて情報漏洩になりかねない

そのため、`HttpClient`クラスは暗黙的に２度もデータを`POST`しない仕様になっているのかもしれません。

* * *

本筋としてはpgrhoさんの提案されている`PreAuthenticate`なのですが、Digest認証ではサーバーから`nonce`を受け取らないことにはハッシュ値を計算できないため原理上PreAuthenticateできません。

同サーバーに対していずれかのページへ`GET`アクセスし、事前にDigest認証を完了させてから`POST`できないでしょうか？


CC BY-SA 3.0
2017-01-11T14:17:30.160
31778
2017-01-11T14:17:30.160
2020-06-17T08:14:45.997
-1
4236
31746
answer