关键字: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. CodeForces 711D Directed Roads (DFS判环+计数)

    题意:给定一个有向图,然后你可能改变某一些边的方向,然后就形成一种新图,让你求最多有多少种无环图. 析:假设这个图中没有环,那么有多少种呢?也就是说每一边都有两种放法,一共有2^x种,x是边数,那么如 ...

  2. UVaLive 6608 Cabin Baggage (水题)

    题意:给定四个数代表长宽高和重,问你是不是满足下面条件,长不高于56,宽不宽于45,高不高于25,或者总和不大于125,并且重量不高于7. 析:判断输出就好,注意这个题是或,不要想错了. 代码如下: ...

  3. 关于mysql存储过程的definer的问题

    由于对mysql了解不够透彻,导致对definer问题查了好久才解决问题 记录自己的一些理解! 问题描述: 在数据库写,为一个表写了一个触发器,此触发器调用一个存储过程:由公司写的一个c程序自动往该表 ...

  4. 25.怎样创建一个Swift项目?

    经历前面三部分的学习之后,我们对于Swift的有了基本的了解,知道它的基础语法,也知道了类.结构体.枚举.协议.扩展等等内容.但知道上面这些内容,并不代表我们就能很好的进行实际的项目开发了,本部分内容 ...

  5. 【转】深入浅出REST

    转自:http://www.infoq.com/cn/articles/rest-introduction 不知你是否意识到,围绕着什么才是实现异构的应用到应用通信的“正确”方式,一场争论正进行的如火 ...

  6. Microsoft Visual C++ Runtime Library Runtime Error的解决的方法

    打开浏览器时,出现Microsoft Visual C++ Runtime Library Runtime Error错误,初步预计是软件冲突,可能有多种出错的方式,我的是浏览器自己主动关闭. 一. ...

  7. 使用iOS手势UIGestureRecognizer

    UIKit中包含了UIGestureRecognizer类,用于检测发生在设备中的手势.UIGestureRecognizer是一个抽象类,定义了所有手势的基本行为,它有下面一些子类用于处理具体的手势 ...

  8. [NodeJS] Deploy a Node Application with the Now CLI

    Now offers a friction-free way to deploy node applications right from the terminal. In this lesson, ...

  9. iOS开发——控制器OC篇&UINavigationController&UITabBarController详解

    UINavigationController&UITabBarController详解 一:UINavigationController 控制器的属性: UINavigationControl ...

  10. iOS开发——UI篇Swift篇&玩转UItableView(三)分组功能

    UItableView分组功能 class UITableViewControllerGroup: UIViewController, UITableViewDataSource, UITableVi ...