zl程序教程

您现在的位置是:首页 >  前端

当前栏目

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

认证Cookie 问题 无法 保存 身份 IE11 forms
2023-06-13 09:15:26 时间
ASP.NET中使用Forms身份认证常见的做法如下:

1.网站根目录下的Web.config添加authentication节点
复制代码代码如下:

<authenticationmode="Forms">
<formsname="MyAuth"loginUrl="manager/Login.aspx"defaultUrl="manager/default.aspx"protection="All"timeout="60"/>
</authentication>

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

<?xmlversion="1.0"?>
<configuration>
<system.web>
<authorization>
<allowroles="Admin"/>
<denyusers="*"/>
</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;
}

stringstrUserName=txt_Username.Text.Trim();
stringmd5Pwd=Helper.MD5ForPHP(Helper.MD5ForPHP(txt_Password.Text));
lc_adminadmin=null;
boollogined=false;

using(varcontext=newdbEntities())
{
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)
{
//UpdateAdminInfo
admin.loginip=Request.UserHostAddress.ToString();
admin.logintime=CndingUtility.DateTimeToUnixTimeStamp(DateTime.Now);
context.SaveChanges();

logined=true;
}
}
}

if(logined)
{
//Login
FormsAuthenticationTicketticket=newFormsAuthenticationTicket(
1,
admin.id.ToString(),
DateTime.Now,
DateTime.Now.AddMinutes(60),
false,
"Admin",
FormsAuthentication.FormsCookiePath
);
stringhashTicket=FormsAuthentication.Encrypt(ticket);
HttpCookieuserCookie=newHttpCookie(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加密代码:
复制代码代码如下:
publicstaticstringMD5ForPHP(stringstringToHash)
{
varmd5=newSystem.Security.Cryptography.MD5CryptoServiceProvider();
byte[]emailBytes=Encoding.UTF8.GetBytes(stringToHash.ToLower());
byte[]hashedEmailBytes=md5.ComputeHash(emailBytes);
StringBuildersb=newStringBuilder();
foreach(varbinhashedEmailBytes)
{
sb.Append(b.ToString("x2").ToLower());
}
returnsb.ToString();
}

认证成功后默认会将用户登录信息以Cookie的形式存放到客户端,有效期为60分钟。UserData被设置为用户的角色,在判断用户是否登录时会用到。如下面的代码:
复制代码代码如下:
if(HttpContext.Current.User.Identity.IsAuthenticated)
{
intadminId=-1;
FormsIdentityidentity=(FormsIdentity)HttpContext.Current.User.Identity;
FormsAuthenticationTicketticket=identity.Ticket;
stringuserData=ticket.UserData;
if(userData=="Admin")
{
//Todosomething
}
}

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

此外,还尝试了降低IE11的安全级别,重新安装服务器上的.netframework以及下载最新的补丁等等,均不能解决问题。后来发现其实只需要简单修改Web.config中authentication节点的设置就可以了,给forms添加cookieless="UseCookies"属性即可。
复制代码代码如下:
<authenticationmode="Forms">
<formsname="MyAuth"cookieless="UseCookies"loginUrl="manager/Login.aspx"defaultUrl="manager/default.aspx"protection="All"timeout="60"/>
</authentication>

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