如何在 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 配置。部署时还需要:
- 为域名申请并安装有效的服务器证书。
- 在 IIS 中为站点添加
https绑定,通常使用端口443。 - 确保证书绑定的主机名与 IPN 地址中的域名一致。
- 在防火墙和负载均衡器上开放 HTTPS 流量。
- 将支付服务商后台登记的通知 URL 改为
https://地址。 - 从外部网络验证证书链、域名和 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 请求,以免用户先从不安全的页面加载表单,再提交敏感信息。
备注:内容仅供参考。
