当前位置: 首页 > 面试题库 >

通过网址提取服务从Google App引擎发送发布请求时,对viewstate MAC进行验证失败

裴甫
2023-03-14
问题内容

我有一个从网站获取html的任务,在转到该页面之前,我需要登录。

我使用了底层API网址提取服务。这是我的代码测试代码:

private String postPage(String loginPageHtml) throws IOException{
    String charset = "UTF-8";
    Document doc = Jsoup.parse(loginPageHtml);
    Iterator<Element> inputHiddensIter =   doc.select("form").first().select("input[type=hidden]").iterator();

    String paramStr = "";

    paramStr += "Username" + "=" + URLEncoder.encode("username", charset) + "&";
    paramStr += "Password" + "=" + URLEncoder.encode("password", charset) + "&";
    paramStr += "ImageButton1.x" + "=" + URLEncoder.encode("50", charset) + "&";
    paramStr += "ImageButton1.y" + "=" + URLEncoder.encode("10", charset) + "&";

    while (inputHiddensIter.hasNext()) {
        Element ele = inputHiddensIter.next();
        String name = ele.attr("name");
        String val = ele.attr("value");
        paramStr += name + "=" + URLEncoder.encode(val, charset) + "&";
    }

    URL urlObj = new URL(LOG_IN_PAGE);
    URLFetchService fetcher = URLFetchServiceFactory.getURLFetchService();
    HTTPRequest request = new HTTPRequest(urlObj, HTTPMethod.POST);
    HTTPHeader header = new HTTPHeader("Content-Type", "application/x-www-form-urlencoded");
    HTTPHeader header3 = new HTTPHeader("Content-Language", "en-US");
    HTTPHeader header4 = new HTTPHeader("User-Agent", DEFAULT_USER_AGENT);
    if(!cookie.isEmpty()){
        request.addHeader(new HTTPHeader("Set-Cookie", cookie));
    }
    request.addHeader(header);
    request.addHeader(header3);
    request.addHeader(header4);
    request.setPayload(paramStr.getBytes());
    request.getFetchOptions().setDeadline(30d);
    HTTPResponse response = null;

    try{
        response = fetcher.fetch(request);
        byte[] content = response.getContent();

        int responseCode = response.getResponseCode();
        log.severe("Response Code : " + responseCode);
        List<HTTPHeader>headers = response.getHeaders();

        for(HTTPHeader h : headers) {
            String headerName = h.getName();
            if(headerName.equals("Set-Cookie")){
                cookie = h.getValue();
            }
        }

        String s = new String(content, "UTF-8");

        return s;
    }catch (IOException e){
        /* ... */
    }

    return "";
}

这是我的默认用户代理:

private static final String DEFAULT_USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.83 Safari/537.1";

它可以在我的开发机上正常工作,但是当我在应用程序引擎上部署并对其进行测试时,我得到响应代码500和以下错误:

验证视图状态MAC失败。如果此应用程序由Web场或群集托管,请确保该配置指定相同的validationKey和验证算法。>
AutoGenerate不能在集群中使用。

说明:执行当前Web请求期间发生未处理的异常。请>检查堆栈跟踪,以获取有关错误及其在代码中起源的更多信息。

异常详细信息:System.Web.HttpException:验证视图状态MAC失败。如果此应用程序由Web场或群集托管,请确保配置指定相同的>
validationKey和验证算法。自动生成不能在群集中使用。

似乎在ASP端发生了一些错误。

我的代码有什么问题或对App Engine的限制吗?


问题答案:

看来您正在POST对aspx页面执行操作。

当aspx页面接收到POST请求时,它会期望一些隐藏的输入,这些隐藏的输入具有已编码的ViewState-
如果浏览到有问题的页面和“查看源代码”,则应该在<form />标记内看到一些类似于以下内容的字段:

<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="xxxxxxxxx" />

因为您提交的POST请求中没有这些值,所以解码和验证它们时会遇到麻烦(这就是错误的含义-在其他情况下,它也会由于其他原因而出现)。

有两种可能的解决方案:

1-如果您有权访问网站的代码,并且登录页面不需要ViewState,则可以尝试在@Page伪指令中的页面级别将其关闭:

<%@ Page ViewStateMode="Disabled" .... %>

2-您可以执行双重请求- GET在登录页面上进行请求以检索所有缺少的隐藏字段的值-使用这些值并将其包括在您的POST

编辑 啊,是的,从您的评论中我可以看到您已经包含了隐藏的表单字段-抱歉!

在这种情况下,另一种可能性是登录页面处于负载平衡的环境中。该环境中的每个服务器将具有一个不同的MachineKey值(用于对ViewState进行编码/解码)。您可能正在阅读中的一个,然后在另一个中发布。一些LB将ArrowPoint
cookie注入响应中,以确保您在请求之间“粘贴”到同一服务器。

我可以看到您已经在其中包含一个cookie
POST,但看不到它的定义位置。是来自第一个GET请求,还是自定义cookie?如果您还没有尝试过,也许尝试使用原始的cookie来GET获取登录页面HTML?除此之外,我没主意-
对不起!



 类似资料:
  • 我尝试了很多解决方案,但都是徒劳的。这就是我按照https://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf的指导方针所做的: > 台阶 对auth请求进行放气,然后对其进行base64编码,最后对其进行Url编码。我们称之为AR Url编码RelayState。我们称之为RS Url编码签名算法字符串。我们称之为S

  • 我在Java客户端有以下代码,它调用基于Spring的REST服务,我得到一个HTTP 400错误。但它与POST man Client完美配合 Java客户端: 服务器端REST服务代码为 现在,当客户端发送请求时,它会给我http 400错误,这可能是因为在客户端,即时消息发送JSON字符串,而在服务器端,它是一个主体,但这在POST MAN上有效 谁能建议我如何通过Java向基于spring

  • 以下是我的情况: < li >客户端向Netty服务器发送POST请求。 < li>Netty处理POST请求,如果服务器确定需要发送响应,它会将响应发送回客户端。否则,服务器必须向另一个endpoint发送POST请求,获取响应并将该响应发送回客户端。 到目前为止,我已经处理了传入的POST请求。要发送传出的POST请求,这是我在Handler中所做的。 这显然是错误的,因为我正在处理程序中启动

  • 问题内容: 我正在尝试通过一个请求将数据从一个node.js服务器发送到另一个node.js服务器。我在“客户端” node.js中执行的操作如下: 该块或多或少是从node.js网站获取的,因此应该正确。我唯一看不到的是如何在变量中包括用户名和密码以进行实际登录。这是我处理服务器node.js中的数据的方式(我使用express): 如何将这些和字段添加到变量中以使其登录? 谢谢 问题答案: 发

  • 我如何发送此信息: 到API: 使用cURL,我目前一直在使用: 其中我得到了结果(NGrok): GET/testDir/curlPost。php HTTP/1.1 接受:text/html、Application/xhtml xml、image/jxr、/ 接受语言:en-GB 用户代理:Mozilla/5.0(Windows NT 10.0;Win64;x64)AppleWebKit/537

  • 我有一个restful请求,需要使用JMeter将其发送到webservice。以下是我的建议: 异常:服务器11.92.0.91在org.apache.commons.httpclient.httpmethodbase.readstatusline(httpmethodbase.java:1976)在org.apache.commons.httpclient.httpmethodbase.jav