自定义授权属性中访问无权限页面时无法获取上一页URL
解决自定义授权属性中AccessDenied页面returnUrl为空的问题
问题原因
当用户直接在地址栏输入无权限页面的URL时,浏览器不会发送Referer请求头(因为没有从其他页面跳转过来),导致你当前代码中获取的returnUrl为空字符串。
解决方案
修改RedirectToAccessDeniedPage方法,优先使用Referer,当Referer为空或无效时, fallback到用户尝试访问的目标URL(当前请求的路径+查询字符串),同时加入本地URL验证防止开放重定向攻击:
private void RedirectToAccessDeniedPage(AuthorizationFilterContext context) { var urlHelper = new UrlHelper(context); string returnUrl = context.HttpContext.Request.Headers["Referer"].ToString(); // 优先用Referer,无效则替换为当前请求的URL if (string.IsNullOrEmpty(returnUrl) || !urlHelper.IsLocalUrl(returnUrl)) { returnUrl = context.HttpContext.Request.Path + context.HttpContext.Request.QueryString; } // 确保最终的returnUrl是本地安全地址,否则跳转到首页 if (!urlHelper.IsLocalUrl(returnUrl)) { returnUrl = "/"; } context.Result = new RedirectToActionResult("AccessDenied", "Account", new { returnUrl }); }
AccessDenied视图优化
在AccessDenied视图中,根据传入的returnUrl动态显示返回链接:
@{ ViewData["Title"] = "无权限访问"; } <h1>无权限访问</h1> <p>你没有权限访问此页面。</p> @if (!string.IsNullOrEmpty(ViewBag.returnUrl)) { <a href="@Url.Content(ViewBag.returnUrl)">返回上一页</a> } else { <a href="/">返回首页</a> }
补充说明
Url.IsLocalUrl用于验证URL是否是当前站点内的地址,避免恶意构造的外部URL导致的安全风险。- 如果用户是从其他页面跳转过来的,会优先回到跳转前的页面;如果是直接输入URL,则回到尝试访问的无权限页面(或首页),保证用户体验的合理性。
内容的提问来源于stack exchange,提问作者Dima Natchkebia
相关产品推荐
相关产品推荐

