基本的には、MVCアプリケーションの一部であるWeb APIコントローラでCross Site Request Forgeryから保護する必要があります。私はどんなアイディアにもオープンしています。この時点で、JavaScript API用のArcGISを使用してEsriマップを表示するMVCビューがあります。ユーザーは地図上にルートを作成し、それが交差するルートとさまざまな機能をAJAX POST経由で保存することができます。ビューにはフォームがありません。これは、サーバーにPOSTするすべてのデータがメモリにあり、画面(または非表示のフィールド)に表示されないためです。Web APIコントローラとCSRFへのAJAX POST
だから、私はantiforgeryトークンを取得するために私のMVCビューで、次があります。
@functions{
public string GetTokenHeaderValue()
{
string cookieToken, formToken;
AntiForgery.GetTokens(null, out cookieToken, out formToken);
return cookieToken + ":" + formToken;
}
}
私はビューで、この隠された入力を持っていたが、それは「形式のトークン」との両方を持っているので、これは悪いです実現しましたAntiForgery.Validationで使用されるクッキーのトークンは:
<input type="hidden" id="antiforgeryToken" value="@GetTokenHeaderValue()" />
はその後、別のJavaScriptファイル(ビュー内のスクリプトタグではありません)、私は私のウェブAPIコントローラへのHTTP POSTをしています。私はリクエストヘッダにトークンを追加する場所です:
var headers = {};
headers['RequestVerificationToken'] = $("#antiforgeryToken").val();
// Ajax POST to Web API Controller
$.ajax({
async: true,
url: '/api/RouteData',
type: 'POST',
headers: headers,
data: requestData,
dataType: 'json',
error: function (xhr, statusText, errorThrown) {
console.log('Error saving route data! ' + errorThrown);
},
success: function (result) {
}
});
注:ページのためのArcGISを使用してのEsriマップを表示するので、体内に掲載取得されたデータは、(すべてのカスタムDojoウィジェットの内部メモリ内にありますJavaScript)。ユーザーがデータを入力していないので、ページ上のフォームはありません)
ウェブAPIコントローラにサーバー側ですべて一緒にそれを結びつける:。
[System.Web.Http.HttpPost]
[ResponseType(typeof(RouteData))]
public async Task<IHttpActionResult> PostRouteData(RouteDataViewModel routeDataVM)
{
try
{
HttpRequestMessage httpRequestMessage = HttpContext.Current.Items["MS_HttpRequestMessage"] as HttpRequestMessage;
ValidateRequestHeader(httpRequestMessage);
}
catch (Exception ex)
{
_logger.Log(LogLevel.Error, ex, ex.Message);
throw;
}
// Now that we know user is who they say they are, perform update
}
void ValidateRequestHeader(HttpRequestMessage request)
{
string cookieToken = "";
string formToken = "";
IEnumerable<string> tokenHeaders;
if (request.Headers.TryGetValues("RequestVerificationToken", out tokenHeaders))
{
string[] tokens = tokenHeaders.First().Split(':');
if (tokens.Length == 2)
{
cookieToken = tokens[0].Trim();
formToken = tokens[1].Trim();
}
}
AntiForgery.Validate(cookieToken, formToken);
}
AntiForgery.Validateが検証するものですトークン。
これは私にいくつかのアイデアを与えてくれたが、私の問題をかなり解決していないこの投稿(http://stackoverflow.com/questions/4074199/jquery-ajax-calls-and-the-html-antiforgerytoken/12116344#12116344 for more possible solutions)を参照してください。多くのクレジットはasp.netのこのポストにも起因します:https://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks。
JavaScriptが別ファイルになっていて、サーバ側のRazor関数を呼び出して偽造防止トークンを取得できないというのは、私にとっては違う点です(私はそう思います)。フォームなしでCSRFを守る方法に関するアイデアはありますか?
あなたの説明は非常に役に立ち、徹底的です。私はHtml.AntiForgeryTokenのMVCの使用を中心に私の心をラップすることができましたが、私は実際にための方法がトークンで使用していることを少し異なるアプローチのAntiForgery.GetTokensを使用しているときから保護されたものへと混同ました。 – iCode
問題ありませんが@iCode - あなたのWeb APIとMVCアプリケーションが同じドメイン上にある場合、あなたはまだ使用していない '@ Html.AntiForgeryToken()'とJSを経由して、フォーム・トークンを抜くことができ、当然のクッキートークン意志は時に送信されそのドメインに対するクッキーの性質上、次のリクエスト。詳細はあなたのリンクされた答えからです:http://stackoverflow.com/a/4074289/698179 –
ああ、はい。私のWeb APIとMVCアプリケーションは同じドメインにあります。今私は私の理解で完全な円になった。実際、フォームトークンとクッキー(クッキートークンを含む)を生成する目的のために単純なフォームを作成することができました。その場合、JSを使用してAJAXポストのデータパラメータにフォームトークンを挿入します。これは、すでにPOSTにデータとして設定しているJSONオブジェクトに加えて追加することができます。私は両方の方法を学ぶためにそれをテストします。 – iCode