一些背景知识
我们的客户希望在完成后返回上一个操作。例如,如果他在对象的列表视图上并且他点击了“创建新对象”按钮,则他希望在填充并保存表单或取消操作后返回列表视图。我们通过模仿未经授权的访问尝试使用的ReturnUrl
行为(将当前地址添加为url编码的查询参数)来实现它。
问题:
如果我没有被授权(或者换句话说没有登录)并尝试访问需要它的操作,我会被重定向到登录页面(正如我所知)并且当前的URL被放入ReturnUrl
param。但是,当当前地址已包含ReturnUrl
查询参数时,我没有被重定向到任何地方,而是得到一个空白页面。这有什么原因吗?
预期结果将被重定向到登录屏幕,并将(url编码版本)当前网址放入ReturnUrl
参数(无论当前网址是否包含其自己的ReturnUrl
参数或不)
有没有办法让它按预期工作?理论上我可以将“ReturnUrl”参数(在我自己的行动中)重命名为其他东西,但我们在很多地方使用过这样的参数已经重命名它们并不是一件容易的事。此外,我真的不明白为什么这首先不起作用。
P.S。如果我将参数命名为ReturnUrl
,如果它是returnUrl
一切正常,那么问题就出现了。
编辑:此问题之前已被调用:如果网址包含名为ReturnUrl的参数,则未经授权访问受限制的操作不会返回任何内容。我更改了标题以便更容易理解。
修改:此问题可能与Unauthorized request does not redirect to login page with returnUrl query string parameter重复。如果那里提供的解决方案能够解决我的问题,我将不得不进一步调查。 更新:措辞相似,但问题毕竟不同,所以不是重复。
答案 0 :(得分:1)
This文章让我走上正轨(负责重定向的是[Authorize]
过滤器),我开始寻找解决方案。经过一些搜索后,我找到了this简单的自定义授权过滤器。当然它没有做我想要的开箱即用(我想要的基本上是授权正常工作但不打破包含ReturnUrl
param的URL),所以我改变了代码得到了这个:
public class Authorize2 : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
// 1. Get the default login url that was declared in web.config
string returnUrl = FormsAuthentication.LoginUrl;
// 2. Append current url as a return url to the login url
returnUrl += "?ReturnUrl=" + HttpUtility.UrlEncode(HttpContext.Current.Request.Url.PathAndQuery);
// 3. ...
// 4. Profit
filterContext.Result = new RedirectResult(returnUrl);
}
}
写完这段代码之后,我又花了一个小时试图弄清楚它为什么不起作用(HandleUnauthorizedRequest
内的断点从未被击中)。然后我找到了this网站,它突然变得有意义了。我的一位同事出于任何原因为所有操作添加了全局Authorize
过滤器,我的自定义过滤器从未被要求授权任何内容( \ App_Start \ FilterConfig.cs )。删除该行后(我最终必须将我的自定义过滤器放在其位置),上面的代码就像一个魅力。
在某种程度上,问题仍然是开放的,我的意思是,为什么授权失败的原因仍然是个谜。毫无疑问,这个问题的答案在于System.Web.Mvc.AuthorizeAttribute
源代码,但是现在我对让它正常工作感到满意。