ASP.NET 支付表单提交需要指导

Posted

技术标签:

【中文标题】ASP.NET 支付表单提交需要指导【英文标题】:ASP.NET Payment Form Submission Need Guidance 【发布时间】:2011-04-24 21:06:45 【问题描述】:

伙计们,如果这个问题没有那么有条理且不够清晰,我深表歉意。我很着急:(

我的 Web 应用有需要提交到另一个 ASP.NET 页面的付款表单(我们称之为http://vendor.com/getpay.aspx) 驻留在另一台服务器上。

该页面将执行一些非常庞大的工作,然后将其重定向到实际 支付网关网站。

当我通过简单的 html 表单将付款表单发布到 getpay.aspx 时,它可以正常工作并重定向。

如果我将表单及其隐藏输入更改为服务器端控件,它就不起作用。他们的页面正在抛出视图状态异常。

    我需要表单隐藏输入作为服务器控件,这样我就可以绑定一些由我的代码生成的值。(我想我可以像使用 的经典 asp 方式一样做到这一点,但这就像去回归标准!) 我在后面的代码中尝试了 HttpWebRequest,它发布了表单,但浏览器没有重定向到支付网关页面。 我通过非 https 发布付款信息,如何防止用户篡改发布的数据?。 我想在后端验证付款表单然后发布,我无法信任用户输入的数据。 结果也返回到我的重定向页面,并附加了查询字符串。它也发生在非 https 上。 我可以在多大程度上信任此重定向数据?

非常感谢

【问题讨论】:

【参考方案1】:

通过清除响应并将 html HTTP 表单重写为清除的响应来生成您的表单。当我回到家时,我会翻阅我的旧代码并提供一个示例。

编辑: 好的,这是我的代码,我不得不重新创建,因为我还在工作,但它有点像这样:

创建一个中间页面以从 ASPX 页面捕获您的变量,然后使用它作为“简单”表单发送:

        protected void Page_Load(object sender, EventArgs e)
        

            // Capture the post to this page
            IDictionary<string, string> variables = new Dictionary<string, string>();

            variables.Add("test", Request.Form["test"]); // collect all variables after checking they exist

            RewriteContent(variable);
        

        public void RewriteContent(IDictionary<string, string> variables)
        
            string formContent = @"
    <html>
        <head>
            <title>My Form</title>
        </head>
        <body>
            <form action='' method=''>";

            foreach (KeyValuePair<string, string> keyVal in variables)
            
                formContent += @"<input type='" + keyVal.Key + "' value='" + keyVal.Value + "' />";
            

        formContent += @"
            </form>
        </body>
    </html>"; // Add either an auto post in a javascript or an explicit submit button

            Response.Clear();
            Response.Write(formContent);
            Response.Flush();
            Response.End();
        

编辑 2: 抱歉,我才意识到我还没有回答其他问题。

第三季度/第四季度/第五季度。如果您不使用 https,则无法真正停止篡改或确保响应正确,但您可以限制它是伪造的机会。这可以通过使用在您的终端和目的地共享的秘密对值进行散列来实现,然后当您获得响应时,您应该对值进行散列并与在您接受它之前发送回给您的散列进行比较有效的。

大多数支付机制都以这种方式验证,通常使用 MD5 或 SHA1 哈希,您可以在以下链接中找到更多信息:

http://msdn.microsoft.com/en-us/library/system.security.cryptography.sha1.aspx http://www.developerfusion.com/code/4601/create-hashes-md5-sha1-sha256-sha384-sha512/ http://snippets.dzone.com/posts/show/5816

编辑 3: 现在做一些加密,我想我会和你分享一些代码(因为我很喜欢那样)。可能会让你知道该怎么做,而且你的代码可能比我更好,所以稍微收拾一下我的烂摊子:)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using log4net;

namespace MyCompany.Cipher

    private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

    public string GenerateSha1HashForString(string valueToHash, EncodeStyle encodeStyle)
    
        string hashedString = string.Empty;

        try
        
            hashedString = SHA1HashEncode(Encoding.UTF8.GetBytes(valueToHash), encodeStyle);
        
        catch (Exception ex)
        
            if (log.IsErrorEnabled)  log.Error(string.Format("0\r\n1", ex.Message, ex.StackTrace)); 
            throw new Exception("Error trying to hash a string; information can be found in the error log", ex);
        

        return hashedString;
    

    private string ByteArrayToString(byte[] bytes, EncodeStyle encodeStyle)
    
        StringBuilder output = new StringBuilder(bytes.Length);

        if (EncodeStyle.Base64 == encodeStyle)
        
            return Convert.ToBase64String(bytes);
        

        for (int i = 0; i < bytes.Length; i++)
        
            switch (encodeStyle)
            
                case EncodeStyle.Dig:
                    //encode to decimal with 3 digits so 7 will be 007 (as range of 8 bit is 127 to -128)
                    output.Append(bytes[i].ToString("D3"));
                    break;
                case EncodeStyle.Hex:
                    output.Append(bytes[i].ToString("X2"));
                    break;
            
        

        return output.ToString();
    

    private string SHA1HashEncode(byte[] valueToHash, EncodeStyle encode)
    
        SHA1 a = new SHA1CryptoServiceProvider();
        byte[] arr = new byte[60];
        string hash = string.Empty;

        arr = a.ComputeHash(valueToHash);
        hash = ByteArrayToString(arr, encode);

        return hash;
    

将它放在你的项目可以看到的某个类中,它可以通过调用公共方法基于字符串值生成 SHA1 哈希。

【讨论】:

我不知道这是否有效,但这是一个非常详细的答案。先生干得好! 抱歉回复晚了。 @Monkieboy 谢谢,我在示例代码中做了..但没有对安全部分做任何事情.. 日程安排很紧,他们只是想让该死的东西正常工作。我正在与他们讨论设置 SSL,如果时间不允许,将完成代码并声明不拥有它。上帝保佑客户!!! 哈哈,祝你好运,记住,即使你加倍努力,你也不会得到任何感谢,客户很少能理解 :)

以上是关于ASP.NET 支付表单提交需要指导的主要内容,如果未能解决你的问题,请参考以下文章

在 asp.net 页面上自动提交表单

ASP.NET MVC 表单提交多层子级实体集合数据到控制器中

防止 Asp.NET 按钮提交表单

提交到 ASP.NET 页面的 PDF 表单创建返回 HTML 文件

请问asp.net中如何在后台代码里提交表单

ASP.NET MVC 网站开发总结——Ajax异步提交表单之检查验证码