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

如果微软继续无视这个问题,我想这就是最简单的解决方法。

 
 
 
标签: ASP.NET

FormsAuthentication登录ReturnUrl使用绝对路径的更多相关文章

  1. [ASP.NET]更简单的方法:FormsAuthentication登录ReturnUrl使用绝对路径

    转自:http://www.cnblogs.com/dudu/p/formsauthentication-returnurl-absoluteuri.html [ASP.NET]更简单的方法:Form ...

  2. FormsAuthentication 登录兼容 IE11 保存cookie

    现象:使用FormsAuthentication进行登录验证,在IE11客户端无法保存cookie 解决方法:在web.config中的forms中增加cookieless="UseCook ...

  3. 【ASP.NET】编程点滴 :ASP.NET身份验证

    ASP.NET实际开发中身份验证 是一个不可回避的问题.在相当一段长的时间内,由于不求甚解,我对这个话题似懂非懂.今天就对它做个简单的小结. Authentication and Authorizat ...

  4. ASP.NET FormsAuthentication跨站点登录时绝对地址返回的问题

    关键字:FormsAuthentication, loginUrl, ReturnUrl, AbsoluteUri 在ASP.NET应用程序中,FormsAuthentication几乎是标配,但Fo ...

  5. 转 asp.net mvc 身份验证中返回绝对路径的ReturnUrl

    原文:http://www.cnblogs.com/hyl8218/archive/2011/11/22/2259116.html 从HttpUnauthorizedResult的源码可以看出,Htt ...

  6. QQ互联登录回调路径错误redirect uri is illegal(100010)

    QQ互联登录设置的路径设置

  7. linux shell中不显示路径了,显示为-bash-4.1#的两种解决办法

    出现这个问题的原因是因为没有配置.bash_profile的问题,或者是我们不小心清空或删除了.bash_profile文件. 办法一:修改 ~/.bash_profile文件 步骤如下: vim ~ ...

  8. 【Linux_Fedora_系统管理系列】_1_用户登录和系统初始配置

    发现一个问题,在FC14 的Firefox浏览器中,编辑和排版好的博文,在windows下用chrome或者猎豹浏览器打开后,排版就变得阅读 不是很容易里,而且经常不经意的断行.不知道园子的管理人员时 ...

  9. Node.js基于Express框架搭建一个简单的注册登录Web功能

    这个小应用使用到了node.js  bootstrap  express  以及数据库的操作 :使用mongoose对象模型来操作 mongodb 如果没了解过的可以先去基本了解一下相关概念~ 首先注 ...

随机推荐

  1. 原因好消息: PSP游戏自己主动算法设计(两)

    这是我们讲的传说中的一项措施A×算法.事实上,类上传之前似小件,下面我们分析一下它去 毕竟,在游戏程序,我们从移动一个点到另一个点.和得到的轨迹的最短距离,类别似这样的算法以及几个.运营效率几乎是相同 ...

  2. phpmyadmin常见错误

    phpmyadmin用root无法登录(username和password都正确) 解决: 看mysqlclient能否够登录(我遇到的是不能登录),若无法登录就更改rootpassword,改好后就 ...

  3. 如何构建高性能web网站:分布式缓存

    一.数据库前端缓冲区 要清除数据库前缓冲区,首先必须明确什么是文件系统的内核缓冲区(Buffer Area):它位于内核的物理内存地址空间,除了使用O_DIRECT比其他标签中打开文件,所有的磁盘的读 ...

  4. Hadoop 2.2.0 HA构造

    在这篇文章中<Ubuntu和CentOS分布式配置Hadoop-2.2.0>介绍hadoop 2.2.0最主要的配置.hadoop 2.2.0中提供了HA的功能,本文在前文的基础上介绍ha ...

  5. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(19)-用户信息的修改和浏览

    原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(19)-用户信息的修改和浏览  ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    ...

  6. jQuery自定义右键菜单

    首先看下效果,效果在最下面: 代码: body { font-size: 12px; margin: 0px; padding: 0px; } form,div,ul,li { margin: 0px ...

  7. LeetCode——Flatten Binary Tree to Linked List

    Given a binary tree, flatten it to a linked list in-place. For example, Given 1 / \ 2 5 / \ \ 3 4 6 ...

  8. jquery 调用wcf 的SOA架构,将三层架构运用到SOA的架构中来(第四天)

    经过前面3天的学习,我想大家应该对SOA的架构有了初步的了解,其实 SOA与三层架构并不冲突,而是三层架构的升级版. 来看下传统的三层架构! 一共可以分为4个层: 模型层(可有可无),客户端,服务端, ...

  9. Shuttle ESB

    Shuttle ESB(六)——在项目中的应用 如果说你认真看了前面几篇关于ESB的介绍,我相信,在这一篇文章中,你将会找到很多共鸣. 尽管,市面上开源的ESB确实非常之多,像Java中的Mule E ...

  10. UITableView Cell 弹簧动画效果

    - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath ...