PAYATHON 2026

如何在 MVC3 应用中为特定操作启用并强制使用 SSL?

支付阿杰

结论

在 ASP.NET MVC 3 中,可以用 RequireHttpsAttribute 要求指定的 Action 或 Controller 只能通过 HTTPS 访问:

[RequireHttps]
public ActionResult PaymentNotification()
{
    // ...
}

此外,还需要在 IIS 中安装站点证书并配置 HTTPS 绑定。支付服务商发送 IPN POST 请求时,回调地址必须直接配置为 https://...,不能依赖 HTTP 自动跳转,否则请求体可能丢失。

为单个 Action 强制使用 HTTPS

在需要保护的操作上添加 [RequireHttps]:

using System.Web.Mvc;

public class PaymentController : Controller
{
    [HttpPost]
    [RequireHttps]
    public ActionResult IpNotification()
    {
        // 读取并验证支付服务商发送的数据

        return new HttpStatusCodeResult(200);
    }
}

对外提供的回调地址应直接使用 HTTPS:

https://www.example.com/Payment/IpNotification

RequireHttpsAttribute 会检查请求是否通过安全连接到达。使用非 HTTPS 协议的请求不会正常执行该 Action。

保护整个 Controller

如果登录、支付或上传相关的所有操作都必须使用 HTTPS,可以在 Controller 上添加该属性:

using System.Web.Mvc;

[RequireHttps]
public class AccountController : Controller
{
    [HttpGet]
    public ActionResult Login()
    {
        return View();
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Login(LoginModel model)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        // 验证用户并建立登录会话
        return RedirectToAction("Index", "Home");
    }
}

Controller 上的 [RequireHttps] 会应用到其中的所有 Action。

集中管理需要 HTTPS 的操作

如果不想在大量 Controller 中重复添加标记,可以创建自定义属性,也可以通过 MVC 过滤器集中配置。如果应用中只有支付、登录和上传等少数入口需要保护,直接使用 [RequireHttps] 往往更清楚,也不容易影响普通页面。

例如,可以创建一个便于扩展的属性:

using System.Web.Mvc;

public sealed class SecureActionAttribute : RequireHttpsAttribute
{
}

然后按需使用:

[SecureAction]
[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
    // 处理上传
    return View();
}

这个封装不会增加新的安全能力,主要用于统一项目内的命名,并为后续策略调整留出空间。

配置 IIS 和证书

[RequireHttps] 只限制 MVC 请求,不能代替服务器端的 SSL/TLS 配置。部署时还需要:

  1. 为域名申请并安装有效的服务器证书。
  2. 在 IIS 中为站点添加 https 绑定,通常使用端口 443。
  3. 确保证书绑定的主机名与 IPN 地址中的域名一致。
  4. 在防火墙和负载均衡器上开放 HTTPS 流量。
  5. 将支付服务商后台登记的通知 URL 改为 https:// 地址。
  6. 从外部网络验证证书链、域名和 TLS 握手是否正常。

本地开发时可以使用开发证书调试,但支付服务商通常要求回调地址可从公网访问,并使用可信证书。具体限制以服务商的回调要求为准。

IPN 请求不能依赖重定向

RequireHttpsAttribute 可以为普通的 HTTP GET 请求生成 HTTPS 重定向,但 IPN 通常使用 POST 请求。不能指望 MVC 3 在重定向这类请求时安全地保留原始请求体。

因此,不要把回调地址配置为:

http://www.example.com/Payment/IpNotification

再期待应用自动跳转到 HTTPS。应直接配置为:

https://www.example.com/Payment/IpNotification

否则,服务商发送的确认字段可能无法到达实际处理请求的 Action。

反向代理和负载均衡环境

如果 TLS 在反向代理或负载均衡器上终止,代理转发到 IIS 的内部请求可能仍然使用 HTTP。此时,MVC 读取到的 Request.IsSecureConnection 可能是 false,导致请求被拒绝或陷入循环跳转。

在这种部署环境中,可信代理需要把原始协议正确传递给应用,应用或 IIS 再根据可信的转发信息判断请求是否使用 HTTPS。不要直接信任客户端提交的任意 X-Forwarded-Proto 请求头,否则攻击者可能伪造该信息。MVC 3 没有现代 ASP.NET Core 提供的完整转发头中间件,具体处理方式取决于代理、IIS 模块和托管架构。

HTTPS 之外仍需完成的安全校验

HTTPS 只能保护数据传输,不能证明回调一定来自支付服务商。IPN Action 还应:

  • 按照服务商的协议验证签名、令牌或回调内容。
  • 必要时向服务商服务器进行二次确认。
  • 核对订单号、金额、币种和收款方。
  • 对重复通知进行幂等处理,避免重复发货或记账。
  • 不在日志中记录密码、完整支付凭据或其他敏感字段。
  • 确认处理成功后,再返回服务商要求的状态码或响应内容。

登录和上传操作也需要全程使用 HTTPS,包括显示表单的 GET 请求和提交数据的 POST 请求,以免用户先从不安全的页面加载表单,再提交敏感信息。

备注:内容仅供参考。