关键字:FormsAuthentication, loginUrl, ReturnUrl, AbsoluteUri

在ASP.NET应用程序中,FormsAuthentication几乎是标配,但FormsAuthentication在设计时却没有考虑登 录程序与当前程序不在同一个站点的场景。这个场景最基本的需求就是去另一个站点登录成功后返回要原地。可是FormsAuthentication在传递 ReturnUrl时只支持相对路径,不支持绝对地址,也没有提供相应的扩展。

比如我们在admin.cnblogs.com站点的web.config中进行了如下的FormsAuthentication设置:

<authentication mode="Forms">
<forms loginUrl="http://passport.cnblogs.com/login.aspx" timeout="2880" enableCrossAppRedirects="true"/>
</authentication>
<authorization>
<deny users="?"/>
</authorization>

访问admin.cnblogs.cc/Home/Index,会被重定向至passport.cnblogs.com/login.aspx?ReturnUrl=%2fHome%2fIndex,这样登录后就回不来了。

那如何解决这个问题呢?

目前找到了三种方法:

方法一:在当前应用程序添加一个登录跳板页,web.config中的loginUrl指向该跳板,在跳板中获取ReturnUrl的绝对地址,再重定向至实际登录页面。

比如在ASP.NET MVC中,我们可以用一个Controller的Action作为跳板,代码如下:

public class LoginController : Controller
{
public ActionResult Redirect()
{
var loginUrl = "http://passport.cnblogs.com/login.aspx";
var returnUrl = "?ReturnUrl=http://" + Request.Url.Host +
Request.QueryString["ReturnUrl"];
return RedirectPermanent(loginUrl + returnUrl);
}
}

然后将web.config中的loginUrl指向该Action。

该方法的缺点是要进行两次重定向。

方法二:在Global.asax的Application_PostAuthenticateRequest事件中将ReturnUrl设置为绝对地址,并重定向至登录页面。

代码如下(代码来自http://forums.asp.net/t/1358796.aspx):

protected void Application_PostAuthenticateRequest(object sender, EventArgs e)
{
if (!UrlAuthorizationModule.CheckUrlAccessForPrincipal(
Request.AppRelativeCurrentExecutionFilePath,
Context.User, Request.RequestType))
{
Response.Redirect(String.Format("{0}?ReturnUrl={1}",
FormsAuthentication.LoginUrl,
Request.Url.AbsoluteUri));
}
}

方法三:在Global.asax的Application_EndRequest事件中修改Response.RedirectLocation,将ReturnUrl的替换为绝对地址。

代码如下(代码来自David Findley's Blog):

protected void Application_EndRequest(object sender, EventArgs e)
{
string redirectUrl = this.Response.RedirectLocation;
if (!string.IsNullOrEmpty(redirectUrl))
{
this.Response.RedirectLocation = Regex.Replace(redirectUrl,
"ReturnUrl=(?'url'.*)", delegate(Match m)
{
string url = HttpUtility.UrlDecode(m.Groups["url"].Value);
Uri u = new Uri(this.Request.Url, url);
return string.Format("ReturnUrl={0}", HttpUtility.UrlEncode(u.ToString()));
}, RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);
}
}

该方法的缺点是要针对所有重定向的URL进行处理,不仅仅是登录。

我们选用的是第二种方法。你是如何解决这个问题的?有没有更好的方法?

这个问题完全归咎于FormsAuthentication的设计问题,当时遇到这个问题,都不敢相信微软没考虑到这个,然后看了一下FormsAuthentication的代码,真是无语。。。

ASP.NET FormsAuthentication跨站点登录时绝对地址返回的问题的更多相关文章

  1. Web Api跨域登录问题

    最近项目第一次尝试使用web api,照搬了一般mvc的Forms登录方式,在和前端对接的时候出现一个问题: 前端使用ajax调用登录接口完成登录后,再调用别的接口,被判断为未登录. 如果直接在浏览器 ...

  2. 网站跨站点单点登录实现--cookie

    至于什么是单点登录,举个例子,如果你登录了msn messenger,访问hotmail邮件就不用在此登录.一般单点登录都需要有一个独立的登录站点,一般具有独立的域名,专门的进行注册,登录,注销等操作 ...

  3. ASP.NET Core中的OWASP Top 10 十大风险-跨站点脚本攻击 (XSS)

    不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译自: https://dotnetcoretutorials.com/201 ...

  4. ASP.NET Core 实现跨站登录重定向的新姿势

    作为 .NET 程序员,痛苦之一是自从 ASP.NET 诞生之日起直到最新的 ASP.NET Core 都无法直接实现跨站登录重定向(比如访问 https://q.cnblogs.com ,跳转到 h ...

  5. 在ASP.NET MVC3 中利用JSONP跨域登录WEB系统

    在信息系统开发的时,根据相关业务逻辑难免会多系统之间互相登录.一般情况下我们需要在多系统之间使用多个用户名和密码.这样客户就需要在多个系统之间重复登陆.每次登录都需要输入用户名和密码.最近比较流行的就 ...

  6. Php开发完全跨站点跨域名单点(SSO)同步登录和注销

    From:http://www.cnblogs.com/JinkoWu/p/5056646.html 先来说说什么是单点登录(SSO).来自百科的介绍:SSO英文全称Single Sign On,单点 ...

  7. 完全跨站点跨域名单点(SSO)同步登录和注销

    先来说说什么是单点登录(SSO).来自百科的介绍:SSO英文全称Single Sign On,单点登录.SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统.它包括可以将这次主 ...

  8. ASP.NET中登录时记住用户名和密码(附源码下载)--ASP.NET

    必需了解的:实例需要做的是Cookie对象的创建和对Cookie对象数据的读取,通过Response对象的Cookies属性创建Cookie,通过Request对象的Cookies可以读取Cookie ...

  9. asp.net mvc 安全测试漏洞 "跨站点请求伪造" 问题解决

    IBM Security Appscan漏洞筛查-跨站请求伪造,该漏洞的产生,有多种情况: 1.WebApi的跨站请求伪造,需要对WebApi的请求头部做限制(此文不做详细介绍): 2.MVC Act ...

随机推荐

  1. Objective-C 学习记录6--dictionary

    1.NSDictionary 和NSMutableDictionary NSDictionary dictionaryWithObjectsAndKeys:~,nil 使用键值对创建字典,用nil标志 ...

  2. Android ImageView scaleType属性

    scaleType属性 文章来源:http://blog.csdn.net/xilibi2003/article/details/6628668 使用ImageView时经常会用到scaleType属 ...

  3. [翻译]比较ADO.NET中的不同数据访问技术(Performance Comparison:Data Access Techniques)

    Performance Comparison: Data Access Techniques Priya DhawanMicrosoft Developer Network January 2002 ...

  4. ao的编辑操作

    自从10.0以后,ArcMap的编辑界面发生了变化,原本的“目标图层”和“编辑任务”不见了,取而代之的是“要素构造”窗口,里面融合了目标图层和编辑任务功能.查看sdk发现,多了几个接口,前面已经讲过. ...

  5. opennebula 创建模板【配置集群、配置VNC、配置RAW、配置SSH】

    { "vmtemplate": { "NAME": "bbbb", "MEMORY": "512", ...

  6. 个人分享:平时开发中感觉几款不错 IDE 、插件、工具

    本人主业 C# 开发,由于是做 Web 开发,所以像 SQL.JavaScript 这些肯定经常要接触到.当然,平时本人也写过 Node.js.Java.Python之类,不过,这些只能讲简单了解而已 ...

  7. JobScheduler

    任务写在JobService中 public class TestJobService extends JobService { private static final String TAG = & ...

  8. PostgreSQL中的AnyEnum例子

    建立函数: CREATE OR REPLACE FUNCTION enumtest(anyenum) RETURNS text AS $$ ::text; $$ LANGUAGE SQL; 建立enu ...

  9. C++学习笔记之友元

    一.引言 C++控制对类对象私有部分(private)的访问,通常只能通过公有的(public)类方法去访问.但是有时候这种限制太严格,不适合特定的问题,于是C++提供了另外一种形式的访问权限:友元. ...

  10. 64位ubuntu下装32位软件

    本帖最后由 wuy069 于 2013-10-25 12:28 编辑 很多软件只有32位的,有的依赖32位库还挺严重的:从ubuntu 13.10已经废弃了ia32-libs,但可以使用多架构,安装软 ...