ASP.NET FormsAuthentication跨站点登录时绝对地址返回的问题
关键字: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跨站点登录时绝对地址返回的问题的更多相关文章
- Web Api跨域登录问题
最近项目第一次尝试使用web api,照搬了一般mvc的Forms登录方式,在和前端对接的时候出现一个问题: 前端使用ajax调用登录接口完成登录后,再调用别的接口,被判断为未登录. 如果直接在浏览器 ...
- 网站跨站点单点登录实现--cookie
至于什么是单点登录,举个例子,如果你登录了msn messenger,访问hotmail邮件就不用在此登录.一般单点登录都需要有一个独立的登录站点,一般具有独立的域名,专门的进行注册,登录,注销等操作 ...
- ASP.NET Core中的OWASP Top 10 十大风险-跨站点脚本攻击 (XSS)
不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译自: https://dotnetcoretutorials.com/201 ...
- ASP.NET Core 实现跨站登录重定向的新姿势
作为 .NET 程序员,痛苦之一是自从 ASP.NET 诞生之日起直到最新的 ASP.NET Core 都无法直接实现跨站登录重定向(比如访问 https://q.cnblogs.com ,跳转到 h ...
- 在ASP.NET MVC3 中利用JSONP跨域登录WEB系统
在信息系统开发的时,根据相关业务逻辑难免会多系统之间互相登录.一般情况下我们需要在多系统之间使用多个用户名和密码.这样客户就需要在多个系统之间重复登陆.每次登录都需要输入用户名和密码.最近比较流行的就 ...
- Php开发完全跨站点跨域名单点(SSO)同步登录和注销
From:http://www.cnblogs.com/JinkoWu/p/5056646.html 先来说说什么是单点登录(SSO).来自百科的介绍:SSO英文全称Single Sign On,单点 ...
- 完全跨站点跨域名单点(SSO)同步登录和注销
先来说说什么是单点登录(SSO).来自百科的介绍:SSO英文全称Single Sign On,单点登录.SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统.它包括可以将这次主 ...
- ASP.NET中登录时记住用户名和密码(附源码下载)--ASP.NET
必需了解的:实例需要做的是Cookie对象的创建和对Cookie对象数据的读取,通过Response对象的Cookies属性创建Cookie,通过Request对象的Cookies可以读取Cookie ...
- asp.net mvc 安全测试漏洞 "跨站点请求伪造" 问题解决
IBM Security Appscan漏洞筛查-跨站请求伪造,该漏洞的产生,有多种情况: 1.WebApi的跨站请求伪造,需要对WebApi的请求头部做限制(此文不做详细介绍): 2.MVC Act ...
随机推荐
- Objective-C 学习记录6--dictionary
1.NSDictionary 和NSMutableDictionary NSDictionary dictionaryWithObjectsAndKeys:~,nil 使用键值对创建字典,用nil标志 ...
- Android ImageView scaleType属性
scaleType属性 文章来源:http://blog.csdn.net/xilibi2003/article/details/6628668 使用ImageView时经常会用到scaleType属 ...
- [翻译]比较ADO.NET中的不同数据访问技术(Performance Comparison:Data Access Techniques)
Performance Comparison: Data Access Techniques Priya DhawanMicrosoft Developer Network January 2002 ...
- ao的编辑操作
自从10.0以后,ArcMap的编辑界面发生了变化,原本的“目标图层”和“编辑任务”不见了,取而代之的是“要素构造”窗口,里面融合了目标图层和编辑任务功能.查看sdk发现,多了几个接口,前面已经讲过. ...
- opennebula 创建模板【配置集群、配置VNC、配置RAW、配置SSH】
{ "vmtemplate": { "NAME": "bbbb", "MEMORY": "512", ...
- 个人分享:平时开发中感觉几款不错 IDE 、插件、工具
本人主业 C# 开发,由于是做 Web 开发,所以像 SQL.JavaScript 这些肯定经常要接触到.当然,平时本人也写过 Node.js.Java.Python之类,不过,这些只能讲简单了解而已 ...
- JobScheduler
任务写在JobService中 public class TestJobService extends JobService { private static final String TAG = & ...
- PostgreSQL中的AnyEnum例子
建立函数: CREATE OR REPLACE FUNCTION enumtest(anyenum) RETURNS text AS $$ ::text; $$ LANGUAGE SQL; 建立enu ...
- C++学习笔记之友元
一.引言 C++控制对类对象私有部分(private)的访问,通常只能通过公有的(public)类方法去访问.但是有时候这种限制太严格,不适合特定的问题,于是C++提供了另外一种形式的访问权限:友元. ...
- 64位ubuntu下装32位软件
本帖最后由 wuy069 于 2013-10-25 12:28 编辑 很多软件只有32位的,有的依赖32位库还挺严重的:从ubuntu 13.10已经废弃了ia32-libs,但可以使用多架构,安装软 ...