ASP.NET Webforms下实现页面仅可通过站内跳转访问且链接单次有效
ASP.NET WebForms 单次有效链接实现方案(.NET 4.0 兼容)
核心逻辑是为每个站内跳转链接生成唯一的一次性校验Token,Token存储在当前用户的服务端Session中,请求页面时校验Token有效性,校验通过立即销毁该Token,实现单次使用限制。
1. 实现Token管理公共类
创建通用类处理Token的生成、存储和校验逻辑:
using System; using System.Collections.Generic; using System.Web; public static class UrlTokenManager { // 存储有效Token的Session键名 private const string ValidTokenSessionKey = "OneTimeAccessTokens"; /// <summary> /// 生成新的一次性访问Token /// </summary> public static string GenerateToken() { string newToken = Guid.NewGuid().ToString("N"); HashSet<string> validTokens = HttpContext.Current.Session[ValidTokenSessionKey] as HashSet<string> ?? new HashSet<string>(); validTokens.Add(newToken); HttpContext.Current.Session[ValidTokenSessionKey] = validTokens; return newToken; } /// <summary> /// 校验Token有效性,校验通过立即销毁该Token /// </summary> public static bool ValidateAndConsumeToken(string token) { if (string.IsNullOrWhiteSpace(token)) return false; HashSet<string> validTokens = HttpContext.Current.Session[ValidTokenSessionKey] as HashSet<string>; if (validTokens == null || !validTokens.Contains(token)) return false; // 移除已使用的Token,实现单次生效 validTokens.Remove(token); HttpContext.Current.Session[ValidTokenSessionKey] = validTokens; return true; } }
2. 所有站内跳转链接拼接Token
生成跳转链接时统一追加一次性Token参数:
后台代码生成链接示例
// 生成商品详情页跳转链接 int productId = 1001; string detailUrl = string.Format("ProductDetail.aspx?id={0}&ot_token={1}", productId, UrlTokenManager.GenerateToken()); // 赋值给HyperLink控件 hlProduct.NavigateUrl = detailUrl;
前台aspx页面直接生成链接示例
<!-- 服务器控件写法 --> <asp:HyperLink ID="hlAbout" runat="server" NavigateUrl='<%# "About.aspx?ot_token=" + UrlTokenManager.GenerateToken() %>' Text="关于页面"> </asp:HyperLink> <!-- 原生a标签写法 --> <a href="Contact.aspx?ot_token=<%= UrlTokenManager.GenerateToken() %>">联系页面</a>
3. 全局请求校验
在Global.asax的Application_BeginRequest事件中添加全局校验逻辑,无需每个页面单独处理:
protected void Application_BeginRequest(object sender, EventArgs e) { string requestPath = Request.Url.AbsolutePath.ToLower(); // 仅校验aspx页面请求,跳过静态资源(css、js、图片等) if (!requestPath.EndsWith(".aspx")) return; // 跳过不需要校验的入口页面,比如首页、登录页等用户可直接访问的页面 if (requestPath == "/default.aspx" || requestPath == "/login.aspx") return; // 获取请求携带的Token string accessToken = Request.QueryString["ot_token"]; // 校验失败直接重定向到错误页 if (!UrlTokenManager.ValidateAndConsumeToken(accessToken)) { Response.Redirect("/AccessError.aspx", true); } }
适配说明
- 表单提交后跳转的目标URL,也需要追加新生成的Token参数
- Token随Session生命周期生效,默认20分钟无操作后失效,可根据需求调整Session超时时间
- 该方案默认不兼容浏览器回退后重复点击同一链接的场景,若需要兼容可调整校验逻辑不销毁Token,配合
Request.UrlReferrer校验即可,但Referer存在伪造风险,安全性低于一次性Token方案
内容的提问来源于stack exchange,提问作者BackofficeDeveloper
相关产品推荐
相关产品推荐

