Http帖子有防伪,令牌,cookie和参数

时间:2014-04-26 22:06:46

标签: android asp.net-mvc-4

我正在尝试从我的Android应用中发布一个帖子到asp.net mvc4网站 但帖子的结果是一个错误页面,其中包含[HttpAntiForgeryException(0x80004005):所需的防伪cookie“__RequestVerificationToken”不存在。]

MVC视图

@model PoliticiOnline.Models.RegisterModel
@{
ViewBag.Title = "Registreer";
}

<link href="@Url.Content("~/Content/registreer.css")" rel="stylesheet" type="text/css" />


@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary()

    <div class="form">

<div id="avatar">
    <img src="~/Content/Images/avatarempty.png" alt="avatar" height="120" width="120">   <br />
    <input class="button" title="avatar" name="avatarbrowse" id="avatarbrowse" value="Blader" type="file">
</div>

<fieldset>
    <ol>
        <li>
            <p class="contact">
            @Html.LabelFor(m => m.UserName)
                </p>
            @Html.TextBoxFor(m => m.UserName)
        </li>
        <li>
            <p class="contact">
            @Html.LabelFor(m => m.Password)
                </p>
            @Html.PasswordFor(m => m.Password)
        </li>
        <li>
            <p class="contact">
            @Html.LabelFor(m => m.ConfirmPassword)
                </p>
            @Html.PasswordFor(m => m.ConfirmPassword)
        </li>

        <li>
            <p class="contact">
            @Html.LabelFor(m => m.Email)
                </p>
            @Html.TextBoxFor(m => m.Email)
        </li>
        <li>
            <p class="contact">
            @Html.LabelFor(m => m.GeboorteDatum)
                </p>
            @Html.TextBoxFor(m => m.GeboorteDatum)
        </li>

        <li>
            <p class="contact">
            @Html.LabelFor(m => m.Naam)
                </p>
            @Html.TextBoxFor(m => m.Naam)
        </li>
        <li>
            <p class="contact">
            @Html.LabelFor(m => m.Voornaam)
                </p>
            @Html.TextBoxFor(m => m.Voornaam)
        </li>

        <li>
            <p class="contact">
            @Html.LabelFor(m => m.Postcode)
                </p>
            @Html.TextBoxFor(m => m.Postcode)
        </li>
        <li>
            <p class="contact">
            @Html.LabelFor(m => m.Geslacht)
                </p>
            @Html.TextBoxFor(m => m.Geslacht)
        </li>

        <li>
            <p class="contact">
            @Html.LabelFor(m => m.Taal)
                </p>
            @Html.TextBoxFor(m => m.Taal)
        </li>
    </ol>
    <input class="button" name="submit" id="submit" tabindex="8" value="Registreer!" type="submit">
    <div id="policy">
        Als je op Registreer klikt bevestig je dat je onze
        <br />
        <a href="@Url.Action("Algvoorw", "Account")" id="voorw" class="">Algemene voorwaarden</a>, en onze <a href="@Url.Action("Privacy", "Account")" id="privacy" class="">Privacy Policy</a>,
        <br />
        en onze  <a href="@Url.Action("GedragsCode", "Shared")" id="gedr" class="">Gedragscode</a>
        inclusief ons gebruik van<br />
        cookies, aanvaardt.
    </div>
</fieldset>

控制器

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult Register(RegisterModel model)
    {
        if (ModelState.IsValid)
        {
            // Attempt to register the user
            try
            {
                if (!WebSecurity.UserExists(model.UserName)) 
                    WebSecurity.CreateUserAndAccount(model.UserName, model.Password, new { Email = model.Email, GeboorteDatum = model.GeboorteDatum, Naam = model.Naam, Voornaam = model.Voornaam, Postcode = model.Postcode, Geslacht = Geslacht.MAN, Taal = Taal.NL, AccountType = AccountType.BURGER, Discriminator = "Burger" });
                if (!Roles.IsUserInRole(model.UserName, "Burger")) Roles.AddUserToRole(model.UserName, "Burger");

                WebSecurity.Login(model.UserName, model.Password);
                return RedirectToAction("Index", "Home");
            }
            catch (MembershipCreateUserException e)
            {
                ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
            }
        }
        // If we got this far, something failed, redisplay form
        return View(model);
    }

Android代码

 @Override
 protected String doInBackground(String... params) {
 // Do request
    DefaultHttpClient httpclient = new DefaultHttpClient();

    try {

        HttpPost httpPost = new HttpPost("http://10.134.216.25:8011/Account/Register");
        httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
        //get cookie
        CookieManager cookieManager = CookieManager.getInstance();
        String cookie = cookieManager.getCookie("10.134.216.25:8011");

        Log.e("Politici", "The cookie is: " + cookie);

        //add cookie to cookiestore
        BasicClientCookie ckie = new BasicClientCookie("__RequestVerificationToken", cookie.replace("__RequestVerificationToken=",""));
        ckie.setPath("http://10.134.216.25:8011/Account/Register");
        ckie.setDomain("http://10.134.216.25:8011");
        CookieStore store = httpclient.getCookieStore();
        store.addCookie(ckie);


        for(Cookie cokie : store.getCookies()){
            Log.e("Politici", cokie.toString());
        }
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
        nameValuePairs.add(new BasicNameValuePair("__RequestVerificationToken",token));
        nameValuePairs.add(new BasicNameValuePair("firstname","as400"));
        nameValuePairs.add(new BasicNameValuePair("lastname","samplecode"));
        httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));


        HttpResponse response = httpclient.execute(httpPost);
        HttpEntity resEntity = response.getEntity();

        Log.e("Politici", response.getStatusLine().toString());
        if (resEntity != null) {
            Log.e("Politici", resEntity.getContentLength() + "");
            Log.e("Politici", resEntity.isChunked() + "");

            String responseBody = EntityUtils.toString(resEntity);
            Log.e("Politici", responseBody);
        }


    }
    catch (Exception e) {
        System.out.println(e);
    }
    finally {
        // When HttpClient instance is no longer needed,
        // shut down the connection manager to ensure
        // immediate deallocation of all system resources
        httpclient.getConnectionManager().shutdown();
    }
    return "";
}

它是一个AsyncTask,而token参数是我从请求源页面获得的值,例如

<input name="__RequestVerificationToken" type="hidden" value="p0-uI4yeEJFyJP8GW3mwTR_b031K-ZqksW8E-hCEaHJi_iGrGJrhmE6Xid1bARGno32KAljv7AHigae8f7S2wGb2m0M1UT_7E7niQ85r0S81" />

这是帖子在页面上的样子。

POST /Account/Register HTTP/1.1
Host: localhost:2334
Proxy-Connection: keep-alive
Content-Length: 334
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://localhost:2334
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)     Chrome/34.0.1847.116 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://localhost:2334/Account/Register
Accept-Encoding: gzip,deflate,sdch
Accept-Language: nl-NL,nl;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: __RequestVerificationToken=XN8W3-H0-btSjGJzEpaW4t5g1tRwNJC-R3CcI3_RpwVDXTRMzW20sR3_nTh7guTC7-nTbPHfDl7uFnTuPOoSGevnENzhUDPbbvMnYBixYRQ1

__RequestVerificationToken=_pnAR4aE3dpcpHt3zGqYpYf0YX3VC7a49mk2UvT-lTJt8_nFGVGHzpOY2LD0J71agcivfxxP2oRTwEjyi3Q5Ty_Y59ZsnX1QEbzsMPERkRo1

&UserName=username
&Password=password
&ConfirmPassword=password
&Email=email%40email.com
&GeboorteDatum=dateofbirth
&Naam=surname
&Voornaam=firstname
&Postcode=2000
&Geslacht=Man
&Taal=NL
&submit=Registreer%21

所以唯一的问题就是让Android上的帖子与我认为的cookie和/或令牌混淆。我做错了什么?

解决: 工作代码

@Override
protected String doInBackground(String... params) {
// Do request
    DefaultHttpClient httpclient = new DefaultHttpClient();

    try {

        HttpPost httpPost = new HttpPost("http://10.134.216.25:8011/Account/Register");
        httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");

        //get cookie
        CookieManager cookieManager = CookieManager.getInstance();
        String cookie = cookieManager.getCookie("10.134.216.25:8011");

        //add cookie to header
        httpPost.setHeader("Cookie", cookie);

        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
        nameValuePairs.add(new BasicNameValuePair("__RequestVerificationToken",token));
        nameValuePairs.add(new BasicNameValuePair("firstname","as400"));
        nameValuePairs.add(new BasicNameValuePair("lastname","samplecode"));
        httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));


        HttpResponse response = httpclient.execute(httpPost);
        HttpEntity resEntity = response.getEntity();

        Log.e("Politici", response.getStatusLine().toString());
        if (resEntity != null) {
            Log.e("Politici", resEntity.getContentLength() + "");
            Log.e("Politici", resEntity.isChunked() + "");

            String responseBody = EntityUtils.toString(resEntity);
            Log.e("Politici", responseBody);
        }


    }
    catch (Exception e) {
        System.out.println(e);
    }
    finally {
        // When HttpClient instance is no longer needed,
        // shut down the connection manager to ensure
        // immediate deallocation of all system resources
        httpclient.getConnectionManager().shutdown();
    }
    return "";
}

1 个答案:

答案 0 :(得分:1)

根据this网站[ValidateAntiForgeryToken]检查以下所有内容:

  1. 请求中有一个名为“__RequestVerificationToken”的cookie。
  2. 请求的格式为NameValuePair,名称为“__RequestVerificationToken”。
  3. 值1和2的值相等。
  4. 以下是使用AntiForgeryToken的全新MVC项目中的注册页面发出的HTTP Post请求。

    POST http://localhost:32887/Account/Register HTTP/1.1
    Host: localhost:32887
    Connection: keep-alive
    Content-Length: 190
    Cache-Control: max-age=0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    Origin: http://localhost:32887
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)
    Chrome/34.0.1847.116 Safari/537.36
    Content-Type: application/x-www-form-urlencoded
    DNT: 1
    Referer: http://localhost:32887/Account/Register
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: en-US,en;q=0.8
    Cookie: __RequestVerificationToken=Y67NY_sxp8tun8hRwfx0_RSG0d0NkJtCr-GbUOFpbRROQ-4kJcJVnIeQEbhiGZP5NCRDutO_JbeuRKp6GaFpe5o6fq8r_Wo8WbcBXPTWot41
    
    __RequestVerificationToken=QpkYjvwoHSKR7eeto0iKigsoI7B01q_mvF99fYih39XMTSptYJc97Xpgi4Qha7pUcbVverpr_nW7RRP4_-7yOpPE0OB7j6_M0LjJlk94VcE1&UserName=asdfgh&Password=asdfgh&ConfirmPassword=asdfgh
    

    我没有尝试过运行代码,但我可以看到两个问题:

    首先,在您的代码中,我无法看到您所在的位置包含NameValuePair,其名称为“__RequestVerificationToken”以满足检查2。

    其次,在我的HTTP请求中,没有“__RequestVerificationToken”HTTP标头。我认为你不需要它。