FormsAuthentication登录ReturnUrl使用绝对路径
ASP.NET]更简单的方法:FormsAuthentication登录ReturnUrl使用绝对路径
被这个问题困扰多年,今天终于找到了更简单的解决方法,分享一下。
问题场景
假设我们在i.cnblogs.com站点的web.config中对FormsAuthentication进行了如下的设置:
<authentication mode="Forms">
<forms name=".cnblogs" loginUrl="https://passport.cnblogs.com/login.aspx" protection="All" path="/"/>
</authentication>
当我们访问一个需要登录后才能访问的URL时,比如:http://i.cnblogs.com/post/list,请求会被重定向至如下的地址:
https://passport.cnblogs.com/login.aspx?ReturnUrl=%2fpost%2flist
瞧!通过ReturnUrl查询参数传递给登录页面的是相对路径——这就是问题所在。由于访问的页面与登录页面不在同一个二级域名下,使用这个相对路径是Return不回来的。
问题的根源
用ILSPY看一下System.Web.Security.FormsAuthentication的代码,立马就能知道问题原因所在:

internal static string GetLoginPage(string extraQueryString, bool reuseReturnUrl)
{
//...
if (text2 == null)
{
text2 = HttpUtility.UrlEncode(current.Request.RawUrl, current.Request.ContentEncoding);
}
text = text + FormsAuthentication.ReturnUrlVar + "=" + text2;
if (!string.IsNullOrEmpty(extraQueryString))
{
text = text + "&" + extraQueryString;
}
return text;
}

由码可见,微软根本就无视了登录页面不在同一个二级域名的基本应用场景,而且一直无视到现在。
以前的解决方法
在当前站点添加一个中转页面,由中转页面重定向至登录页面。
于是,web.config的设置变成了如下的样子,先重定向至当前站点的登录中转页面。
<authentication mode="Forms">
<forms name=".cnblogs" loginUrl="~/account/login" protection="All" path="/"/>
</authentication>
然后,在中转页面使用绝对路径作为ReturnUrl的值,再重定向至真正的登录页面。
中转页面的示例代码如下:

public class AccountController : Controller
{
public ActionResult Login(string ReturnUrl)
{
return Redirect("https://passport.cnblogs.com/login.aspx?ReturnUrl=" +
HttpUtility.UrlEncode("http://" + Request.Url.Host) + ReturnUrl);
}
}

虽然解决了问题,但是对于这样的解决方法,我觉得有些啰嗦,总觉得有更好的解决方法,可是一直没找到。
今天再次面对这个问题时,狠了一下心,竟然有了意外的收获!
更简单的解决方法
Forms验证中,工作在第一线、最苦最累的是System.Web.Security.FormsAuthenticationModule。
它在OnEnter(object source, EventArgs eventArgs)中调用了OnAuthenticate方法:

// System.Web.Security.FormsAuthenticationModule
private void OnEnter(object source, EventArgs eventArgs)
{
//...
this.OnAuthenticate(new FormsAuthenticationEventArgs(context));
//...
}

而在OnAuthenticate()方法中有如下的事件处理:

private void OnAuthenticate(FormsAuthenticationEventArgs e)
{
HttpCookie httpCookie = null;
if (this._eventHandler != null)
{
this._eventHandler(this, e);
}
//...
}

再找到有关这个事件的代码:

// System.Web.Security.FormsAuthenticationModule
public event FormsAuthenticationEventHandler Authenticate
{
add
{
this._eventHandler = (FormsAuthenticationEventHandler)Delegate.Combine(this._eventHandler, value);
}
remove
{
this._eventHandler = (FormsAuthenticationEventHandler)Delegate.Remove(this._eventHandler, value);
}
}

从这个地方下手,更简单的解决方法就浮出了水面——
在Global.asax.cs中添加如下的代码:

public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
//...
} protected void FormsAuthentication_OnAuthenticate(Object sender,
FormsAuthenticationEventArgs e)
{
if (Request.Cookies[FormsAuthentication.FormsCookieName] == null)
{
Response.Redirect(FormsAuthentication.LoginUrl + "?ReturnUrl=" +
HttpUtility.UrlEncode(e.Context.Request.Url.AbsoluteUri));
}
}
}

web.config中使用原先的设置:
<authentication mode="Forms">
<forms name=".cnblogs" loginUrl="https://passport.cnblogs.com/login.aspx" protection="All" path="/"/>
</authentication>
访问http://i.cnblogs.com/post/list时,会进行如下的重定向:
https://passport.cnblogs.com/login.aspx?ReturnUrl=http%3a%2f%2fi.cnblogs.com/post/list
如果微软继续无视这个问题,我想这就是最简单的解决方法。
FormsAuthentication登录ReturnUrl使用绝对路径的更多相关文章
- [ASP.NET]更简单的方法:FormsAuthentication登录ReturnUrl使用绝对路径
转自:http://www.cnblogs.com/dudu/p/formsauthentication-returnurl-absoluteuri.html [ASP.NET]更简单的方法:Form ...
- FormsAuthentication 登录兼容 IE11 保存cookie
现象:使用FormsAuthentication进行登录验证,在IE11客户端无法保存cookie 解决方法:在web.config中的forms中增加cookieless="UseCook ...
- 【ASP.NET】编程点滴 :ASP.NET身份验证
ASP.NET实际开发中身份验证 是一个不可回避的问题.在相当一段长的时间内,由于不求甚解,我对这个话题似懂非懂.今天就对它做个简单的小结. Authentication and Authorizat ...
- ASP.NET FormsAuthentication跨站点登录时绝对地址返回的问题
关键字:FormsAuthentication, loginUrl, ReturnUrl, AbsoluteUri 在ASP.NET应用程序中,FormsAuthentication几乎是标配,但Fo ...
- 转 asp.net mvc 身份验证中返回绝对路径的ReturnUrl
原文:http://www.cnblogs.com/hyl8218/archive/2011/11/22/2259116.html 从HttpUnauthorizedResult的源码可以看出,Htt ...
- QQ互联登录回调路径错误redirect uri is illegal(100010)
QQ互联登录设置的路径设置
- linux shell中不显示路径了,显示为-bash-4.1#的两种解决办法
出现这个问题的原因是因为没有配置.bash_profile的问题,或者是我们不小心清空或删除了.bash_profile文件. 办法一:修改 ~/.bash_profile文件 步骤如下: vim ~ ...
- 【Linux_Fedora_系统管理系列】_1_用户登录和系统初始配置
发现一个问题,在FC14 的Firefox浏览器中,编辑和排版好的博文,在windows下用chrome或者猎豹浏览器打开后,排版就变得阅读 不是很容易里,而且经常不经意的断行.不知道园子的管理人员时 ...
- Node.js基于Express框架搭建一个简单的注册登录Web功能
这个小应用使用到了node.js bootstrap express 以及数据库的操作 :使用mongoose对象模型来操作 mongodb 如果没了解过的可以先去基本了解一下相关概念~ 首先注 ...
随机推荐
- Oracle按不同时间分组统计
Oracle按不同时间分组统计 Oracle按不同时间分组统计的sql 如下表table1: 日期(exportDate) 数量(amount) -------------- ----------- ...
- MSMQ-发送消息到远程专用队列 实例
目录 一:MSMQ的一些理论上的知识 二:队列类型(Queue Type) 三:安装消息队列 四:在C#中Messagequeue class 五:MSMQ-发送消息到远程专用队列 六:例子 一. ...
- 小记 js unicode 编码解析
原文:小记 js unicode 编码解析 var str = "\\u6211\\u662Funicode\\u7F16\\u7801"; 关于这样的数据转换为中文问题,常用的两 ...
- hdu1086(线段相交)
题目意思: 给出n个线段,推断这n条线段中,线段相交的对数. http://acm.hdu.edu.cn/showproblem.php?pid=1086 题目分析: 此题主要写出推断线段相交的函数, ...
- JQUERY prop与attr差额
1. 1-9-1之前和之后之间的差 <html> <script src="Js/jquery-1.9.0.js" type="text/javasc ...
- cmd介面,进adb命令提示符error
有几个操作的电话系统测试,需要输入adb命令时出现了头疼的事,当输入命令,一个直接报执行:error 推荐处理的方法: 1.当然就是关机重新启动.之前我是这样,挺麻烦.必进在win7上输入命令费时间. ...
- java_model_dao_自动生成_generator-mybatis-generator-1.3.2 基于maven插件
用mybatis原因很简单,易用,性能.是介于jdbc和hibernate之间的一个完美方案. 很简单: 1:配置pom <project xmlns="http://maven.ap ...
- STL源代码分析——STL算法sort排序算法
前言 因为在前文的<STL算法剖析>中,源代码剖析许多,不方便学习,也不方便以后复习.这里把这些算法进行归类,对他们单独的源代码剖析进行解说.本文介绍的STL算法中的sort排序算法,SG ...
- CentOs Linux 常见命令
整理一些常用的命令(持续更新): 查看端口是否开启: netstat -an | grep prot (查看是否打开23端口) |:通道的意思,grep是指查看当前字符所在的行 LINUX通过下面的命 ...
- Critical thinking and Thoughtful writing
Critical thinkers are able to : Articulate their ideas clearly and persuasively in writing Understan ...