android - 带防伪、token、cookie 和参数的 Http post

标签 android asp.net-mvc-4

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

MVC View

@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>

Controller

    [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);
    }

安卓代码

 @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 和/或 token 。我做错了什么?

已解决: 工作代码

@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 "";
}

最佳答案

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

  1. 请求有一个名为“__RequestVerificationToken”的 cookie。
  2. 请求具有名称为“__RequestVerificationToken”的 NameValuePair 表单。
  3. 1和2的值相等。

下面是在一个全新的 MVC 项目中从注册页面发出的 HTTP Post 请求,它使用了 AntiForgeryToken

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

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

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

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

关于android - 带防伪、token、cookie 和参数的 Http post,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23317021/

相关文章:

android - 如何在 Android 中以编程方式更改应用程序图标?

asp.net-mvc-4 - 从 beta 升级后 Autofac/MVC4/WebApi (RC) 依赖注入(inject)问题

javascript - 是否可以以不同的形式共享一键点击?

javascript - ASP.NET MVC 表单 : Can submit with ENTER key but not Submit button

android - 当我单击 fragment B 的发送按钮时如何将 arrayList 传递给 fragment C

android - Gradle Android Studio中的错误

android - 我可以在我的 android 应用程序中使用哪些控件?

asp.net - SSL 身份验证导致 MVC 4 站点出现问题

c# - 在 VS2012 中创建新的 ASP.NET MVC 4 Web 应用程序时出现 0x80070002 错误

android - 如何使用 LocationManager 在 android 中获取当前位置