🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
cURL

cURLはHTTP, FTPやTelnetなど複数のプロトコルを用いてデータを転送するライブラリとコマンドラインツールを提供します。

HTTPS

HTTPS(Hypertext Transfer Protocol Secure)はHypertext Transfer プロトコルとSSL/TLS プロトコルを組み合わせたものです。WebサーバとWebブラウザの間の通信を暗号化させて、通信経路上での盗聴や第三者によるなりすましを防止します。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

2回答

4648閲覧

C# HttpClientで複数回HTTPSリクエストを送信したい

sato4000

総合スコア42

cURL

cURLはHTTP, FTPやTelnetなど複数のプロトコルを用いてデータを転送するライブラリとコマンドラインツールを提供します。

HTTPS

HTTPS(Hypertext Transfer Protocol Secure)はHypertext Transfer プロトコルとSSL/TLS プロトコルを組み合わせたものです。WebサーバとWebブラウザの間の通信を暗号化させて、通信経路上での盗聴や第三者によるなりすましを防止します。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

1クリップ

投稿2019/09/26 06:36

編集2019/09/26 11:04

HttpClientでデータをサーバへPOSTしたいのですが、エラーが返ってきます。
HttpClientで複数回HTTPSリクエストを送信する場合に、何かしなければいけないことなどありますでしょうか?
又、Authorizationヘッダの設定の仕方はあっていますでしょうか?ご教示願います。
下記curlコマンドで実行した場合は正常に成功しました。

curl

1curl -X POST -d "username=xxxxx&password=xxxxx" https://xxx/xxx/xxx/ -x http://xxx:xxx@xxx:8080 2↑このコマンドでtoken取得(aaa) 3 4curl -X POST -H "Authorization: aaa" -d "sex=xxx&year=xxx&occ=xxx&area=xxx" https://xxx/yyy/yyy/ -x http://xxx:xxx@xxx:8080 5

C#

1 string proxyAccount = ProxyUser.Text; 2 string proxyPassword = ProxyPassword.Text; 3 string proxyUrl = "http://" + Proxy.Text + ":" + Port.Text; 4 5 WebRequest.DefaultWebProxy.Credentials = new NetworkCredential(proxyAccount, proxyPassword); 6 7 // HttpClientHandlerにProxy情報を設定する 8 HttpClientHandler ch = new HttpClientHandler(); 9 ch.Proxy = new WebProxy(proxyUrl, false); 10 ch.Proxy.Credentials = new NetworkCredential(proxyAccount, proxyPassword); 11 ch.UseProxy = true; 12 13 HttpClient client = new HttpClient(ch); 14 15 Uri tokenuri = new Uri(URL.Text + "/xxx/xxx/"); 16 17 HttpRequestMessage tokenrequest = new HttpRequestMessage(HttpMethod.Post, tokenuri); 18 19 var contentList = new List<string>(); 20 contentList.Add("username=" + User.Text); 21 contentList.Add("password=" + Password.Text); 22 23 tokenrequest.Content = new StringContent(string.Join("&", contentList), 24 Encoding.UTF8, 25 "application/x-www-form-urlencoded");//CONTENT-TYPE header 26 27 var response = await client.SendAsync(tokenrequest); 28 string token = await response.Content.ReadAsStringAsync(); 29        30         //省略 レスポンスからtokenのみ取り出す。 31 32 Uri adduri = new Uri(URL.Text + "/yyy/yyy/"); 33 34 HttpRequestMessage addrequest = new HttpRequestMessage(HttpMethod.Post, adduri); 35 36 var contentList2 = new List<string>(); 37 contentList2.Add("sex=xxx"); 38 contentList2.Add("year=xxx"); 39 contentList2.Add("occ=xxx"); 40 contentList2.Add("area=xxx"); 41 42 addrequest.Headers.Add("Authorization", token); 43 addrequest.Content = new StringContent(string.Join("&", contentList2), 44 Encoding.UTF8, 45 "application/x-www-form-urlencoded");//CONTENT-TYPE header 46 47 var addresponse = await client.SendAsync(addrequest);

試したこと
・curlコマンドで実行した場合は、正常にデータを取得できた。
・上記ソースコードでは二回目のリクエスト送信に対して403エラーが返ってきた。
・tokenは正常に取得できた。
・curlコマンドで間違えたtokenを設定した場合やbody部のパラメータを間違えた場合でも403レスポンスは返ってこなかった。
・一つ目と二つ目のリクエストの間に20秒くらい時間を空けてもエラーが返ってきた。
・一つ目のトークンをとるリクエストを消して、あらかじめとっておいたトークンを固定で使用して二つ目のリクエストだけ送信したら200OKがかえってきて成功した。
固定で使用したトークンと一つ目のリクエストでとってくるトークンを比較したが全く同じ値。
・よくないことだと思うが、HttpClientやHttpClientHandlerを新たにもう一つ作成したらどちらのリクエストも成功した。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/09/27 04:27

サーバー側(Web API)の仕様が分からないと答えを得るのは難しいと思います。認証に使用されるトークンにかかわる問題のようですが、少なくともそのあたりの詳細な仕様は書けませんか? もしくは、ごく一般的なフレームワークを利用して実装された Web API であれば、それが何かを書いてもらうとか。(例えば、.NET Framework ベースの ASP.NET Web API でごく普通にデフォルトのベアラトークンを利用しているとかであれば、詳細仕様を書いてもらわなくても自分はある程度わかりますから)
退会済みユーザー

退会済みユーザー

2019/09/27 04:29

あと、プロキシ経由のようですが、であれば、その影響を排除して(プロキシを通さないようにして)調べてみることはできますか?
sato4000

2019/10/02 12:08

プロキシサーバを経由しない環境でも同じ結果でした。 >サーバー側(Web API)の仕様が分からないと答えを得るのは難しいと思います。 そうですよね。もうしわけありませんが、curlの例とパラメータしか教わっていないため、私も詳細な仕様を理解しておりません。 とりあえずHttpClientとHttpClientHandlerを二つ用意しておけばデータを取得できたので、詳細な仕様を教えてもらうまで我慢したいと思います。(開示してくれるかわかりませんが)
sato4000

2019/10/02 12:09

コメントいただきありがとうございます。
guest

回答2

0

HTTP 403が返ってくるってことは、HTTPサーバとの通信には問題ないことが予想されます。
ましてや一回目に正常に通信できているなら、リクエストの書き方自体は問題ないでしょう。

HTTP 403はHTTPサーバ側の判断で返すものなので、本当の事情はHTTPサーバ側でしか分かりません。
しかし単純に
・DoS攻撃対策として同じIPからのリクエストは一定期間受け付けない とか
・前のリクエストが処理中で新たなリクエストを処理できない とか
なら暫く時間を置いてから次のリクエストを送るようにしたら良いでしょう。

以下余談です。
本件とは関係ありませんが、複数回アクセスするならHttpClientは使いまわすことをお勧めします。
不適切なインスタンス化のアンチパターン

投稿2019/09/26 07:54

hihijiji

総合スコア4152

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sato4000

2019/09/26 09:28

ご回答いただきありがとうございます。 一定時間処理をあけて試してみます。
sato4000

2019/09/26 09:52

20秒くらい時間を空けても変わりませんでした。一つ目のトークンをとるリクエストを消して、あらかじめとっておいたトークンを使用して二つ目のリクエストだけ送信したらなぜか200OKがかえってきて成功しました。
hihijiji

2019/09/27 07:01

単純な理由じゃなかったようですね。 事情はHTTPサーバ側でしか分かりませんから、配布されていればドキュメントを読むかサービス提供側に問い合わせるしかありません。
sato4000

2019/10/02 12:10

コメントいただきありがとうございます。 問い合わせてみたいと思います。
guest

0

自己解決

あまりよくない実装方法ではあるのかもしれませんが、HttpClientやHttpClientHandlerを二つ用意してトークン取得用とデータ取得用で分けることで、無事データが取得できました。

投稿2019/10/02 12:12

sato4000

総合スコア42

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問