Forms身份认证在IE11下无法保存Cookie的问题

ASP.NET中使用Forms身份认证常见的做法如下:

1. 网站根目录下的Web.config添加authentication节点


复制代码 代码如下:

<authentication mode="Forms">
<forms name="MyAuth" loginUrl="manager/Login.aspx" defaultUrl="manager/default.aspx" protection="All" timeout="60" />
</authentication>

2. 在manager子目录下添加Web.config文件并加入下面的内容:


复制代码 代码如下:

<?xml version="1.0"?>
<configuration>
<system.web>
<authorization>
<allow roles="Admin" />
<deny users="*" />
</authorization>
</system.web>
</configuration>

这样,用户在没有Forms认证的情况下访问manager子目录下的任何页面均会自动跳转到manager/Login.aspx页面。如果认证成功,则会默认回到manager/default.aspx页面。认证有效期为60分钟。

3. 添加认证代码。登录按钮中添加下面的代码:


复制代码 代码如下:

if (!snCheckCode.CheckSN(txt_ValidateCode.Text))
{
snCheckCode.Create();
Utility.ShowMessage("校验码错误!");
return;
}

string strUserName = txt_Username.Text.Trim();
string md5Pwd = Helper.MD5ForPHP(Helper.MD5ForPHP(txt_Password.Text));
lc_admin admin = null;
bool logined = false;

using (var context = new dbEntities())
{
admin = context.tb_admin.Where(n => n.username == strUserName).FirstOrDefault();

if (admin != null)
{
if (admin.checkadmin != "true")
{
snCheckCode.Create();
Utility.ShowMessage("抱歉,该账号被禁止登录!");
return;
}

if (admin.password == md5Pwd)
{
// Update Admin Info
admin.loginip = Request.UserHostAddress.ToString();
admin.logintime = CndingUtility.DateTimeToUnixTimeStamp(DateTime.Now);
context.SaveChanges();

logined = true;
}
}
}

if (logined)
{
// Login
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
1,
admin.id.ToString(),
DateTime.Now,
DateTime.Now.AddMinutes(60),
false,
"Admin",
FormsAuthentication.FormsCookiePath
);
string hashTicket = FormsAuthentication.Encrypt(ticket);
HttpCookie userCookie = new HttpCookie(FormsAuthentication.FormsCookieName, hashTicket);
HttpContext.Current.Response.Cookies.Add(userCookie);

if (Request["ReturnUrl"] != null)
{
Response.Redirect(HttpUtility.HtmlDecode(Request["ReturnUrl"]));
}
else
{
Response.Redirect("/manager/default.aspx");
}
}
else
{
snCheckCode.Create();
CndingUtility.ShowMessage("用户名或密码不正确!");
}

MD5加密代码:


复制代码 代码如下:

public static string MD5ForPHP(string stringToHash)
{
var md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] emailBytes = Encoding.UTF8.GetBytes(stringToHash.ToLower());
byte[] hashedEmailBytes = md5.ComputeHash(emailBytes);
StringBuilder sb = new StringBuilder();
foreach (var b in hashedEmailBytes)
{
sb.Append(b.ToString("x2").ToLower());
}
return sb.ToString();
}

认证成功后默认会将用户登录信息以Cookie的形式存放到客户端,有效期为60分钟。UserData被设置为用户的角色,在判断用户是否登录时会用到。如下面的代码:


复制代码 代码如下:

if (HttpContext.Current.User.Identity.IsAuthenticated)
{
int adminId = -1;
FormsIdentity identity = (FormsIdentity)HttpContext.Current.User.Identity;
FormsAuthenticationTicket ticket = identity.Ticket;
string userData = ticket.UserData;
if (userData == "Admin")
{
// To do something
}
}

上述代码在Visual Studio中运行一切正常!但是将网站发布到服务器的IIS (可能会是较低版本的IIS,如IIS 6)后,发现登录功能异常。输入用户名和密码后点击登录按钮,页面postback但并不能正确跳转,尝试手动访问受保护的页面会被自动跳转回登录页面。更奇怪的是该问题只出现在IE11浏览器上,尝试用Firefox或Chrome访问登录功能运行正常。初步怀疑是IIS设置的问题,可是IIS 6上并没有与Cookie相关的设置,好像记得IIS 7上倒是有这个设置。但因为只有IE 11存在该问题,所以可以否定代码本身存在任何问题。

此外,还尝试了降低IE 11的安全级别,重新安装服务器上的.net framework以及下载最新的补丁等等,均不能解决问题。后来发现其实只需要简单修改Web.config中authentication节点的设置就可以了,给forms添加cookieless="UseCookies"属性即可。


复制代码 代码如下:

<authentication mode="Forms">
<forms name="MyAuth" cookieless="UseCookies" loginUrl="manager/Login.aspx" defaultUrl="manager/default.aspx" protection="All" timeout="60" />
</authentication>

用以明确告诉服务器使用Cookie来保存用户验证信息。问题解决!

时间: 2014-05-04

ASP.NET Forms身份认证详解

ASP.NET身份认证基础 在开始今天的内容之前,我想有二个最基础的问题首先要明确: 1. 如何判断当前请求是一个已登录用户发起的? 2. 如何获取当前登录用户的登录名? 在标准的ASP.NET身份认证方式中,上面二个问题的答案是: 1. 如果Request.IsAuthenticated为true,则表示是一个已登录用户. 2. 如果是一个已登录用户,访问HttpContext.User.Identity.Name可获取登录名(都是实例属性). 接下来,本文将会围绕上面二个问题展开,请继续阅读

ASP.NET Forms身份认证

asp.net程序开发,用户根据角色访问对应页面以及功能. 项目结构如下图: 根目录 Web.config 代码: <?xml version="1.0" encoding="utf-8"?> <!-- 有关如何配置 ASP.NET 应用程序的详细消息,请访问 http://go.microsoft.com/fwlink/?LinkId=169433 --> <configuration> <system.web> &

一个简单的ASP.NET Forms 身份认证的实例方法

Web.config 复制代码 代码如下: <configuration> <system.web>  <compilation debug="true"/>  <authentication mode="Forms">   <forms loginUrl="login.aspx" name = ".ASPXFORMSAUTH" />  </authentica

ASP.NET 2.0 中Forms安全认证

即:使用 Membership 类 + FormsAuthentication 一起使用以创建的用户管理与认证的系统. 当然这两部分都可以单独使用,今天先着重后者,至于前者,我下一篇随笔将会写到. ASP.NET 中提供了多种认证方式,比如大名鼎鼎的Windows 身份验证 Windows 身份验证模式根据 IIS 所提供的凭据将当前 User 属性值设置为 WindowsIdentity,但它不修改提供给操作系统的 Windows 标识.提供给操作系统的 Windows 标识用于进行权限检查(

ASP.NET学习CORE中使用Cookie身份认证方法

大家在使用ASP.NET的时候一定都用过FormsAuthentication做登录用户的身份认证,FormsAuthentication的核心就是Cookie,ASP.NET会将用户名存储在Cookie中. 现在到了ASP.NET CORE的时代,但是ASP.NET CORE中没有FormsAuthentication这个东西,那么怎么做身份认证呢?答案是ASP.NET CORE已经为我们内置了Cookie身份认证的功能,而且使用起来非常方便,注意本文是基于ASP.NET CORE 2.0版本

AngularJS 应用身份认证的技巧总结

在web中很多时候都能应用到身份认证,本文介绍了AngularJS 应用身份认证的技巧,废话不多说了一起往下看吧. 身份认证 最普遍的身份认证方式就是用用户名(或 email)和密码做登陆操作.这就意味要实现一个登陆的表单,以便用户能够用他们个人信息登陆.这个表单看起来是这样的: <form name="loginForm" ng-controller="LoginController" ng-submit="login(credentials)&q

asp.net mvc中Forms身份验证身份验证流程

验证流程 一.用户登录 1.验证表单:ModelState.IsValid 2.验证用户名和密码:通过查询数据库验证 3.如果用户名和密码正确,则在客户端保存Cookie以保存用户登录状态:SetAuthCookie     1):从数据库中查出用户名和一些必要的信息,并把额外信息保存到UserData中 2):把用户名和UserData保存到 FormsAuthenticationTicket 票据中 3):对票据进行加密 Encrypt 4):将加密后的票据保存到Cookie发送到客户端 4

MongoDB安全及身份认证(实例讲解)

前面的话 本文将详细介绍MongoDB安全相关的内容 概述 MongoDB安全主要包括以下4个方面 1.物理隔离 系统不论设计的多么完善,在实施过程中,总会存在一些漏洞.如果能够把不安全的使用方与MongoDB数据库做物理上的隔离,即通过任何手段都不能连接到数据库,这是最安全的防护.但,通常这是不现实的.一些重要的数据可能会保存下来,放置到物理隔离的机房中 2.网络隔离 许多公司的开发机处于内网环境中.即使数据库存在漏洞,外部环境也没有机会利用,因为根本无法访问内网 3.防火墙隔离 可以利用防火

详解在ASP.NET Core中使用Angular2以及与Angular2的Token base身份认证

Angular2是对Angular1的一次彻底的,破坏性的更新. 相对于Angular1.x,借用某果的广告语,唯一的不同,就是处处都不同. •首先,推荐的语言已经不再是Javascript,取而代之的TypeScript,(TypeScript = ES6 + 类型系统 + 类型注解), TypeScriipt的类型系统对于开发复杂的单页Web app大有帮助,同时编译成javascript后的执行效率也比大多数手写javascript要快.有兴趣的同学可以查阅官方文档:英文传送门 |中文传送