ASP.NET中使用Forms身份认证常见的作法以下:web
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. 添加认证代码。登陆按钮中添加下面的代码:cookie
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加密代码:less
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被设置为用户的角色,在判断用户是否登陆时会用到。以下面的代码:ide
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存在该问题,因此能够否认代码自己存在任何问题。post
此外,还尝试了下降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来保存用户验证信息。问题解决!ui