Having trouble with authentication in asp.net web application
我正在尝试对从登录页面登录到我的Web应用程序的用户进行身份验证。我使用本教程作为指南,它非常准确地解释了我希望做什么,但是当我输入用户名和密码时,验证不起作用。请允许我解释一下。
以下是我的HTML的相关部分。一切正常:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <form id="form1" runat="server"> <input id="txtUserName" type="text" runat="server"> <ASP:RequiredFieldValidator ControlToValidate="txtUserName" Display="Static" ErrorMessage="*" runat="server" ID="vUserName" /> <input id="txtUserPass" type="password" runat="server"> <ASP:RequiredFieldValidator ControlToValidate="txtUserPass" Display="Static" ErrorMessage="*" runat="server" ID="vUserPass" /> <p> </p> <input type="submit" Value="Logon" runat="server" ID="cmdLogin"><p> </p> <ASP:CheckBox id="chkPersistCookie" runat="server" autopostback="false" /> </form> |
页面包含一个用户名和一个登录按钮(以及一个记忆cookie的复选框,但我认为这与我的问题无关)。
下面是代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data.SqlClient; using System.Web.Security; namespace MRAApplication { public partial class _1__0__0__0_LoginScreen : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { this.cmdLogin.ServerClick += new System.EventHandler(this.cmdLogin_ServerClick); } private bool ValidateUser(string userName, string passWord) { SqlConnection conn; SqlCommand cmd; string lookupPassword = null; // Check for invalid userName. // userName must not be null and must be between 1 and 15 characters. if ((null == userName) || (0 == userName.Length) || (userName.Length > 15)) { System.Diagnostics.Trace.WriteLine("[ValidateUser] Input validation of userName failed."); return false; } // Check for invalid passWord. // passWord must not be null and must be between 1 and 25 characters. if ((null == passWord) || (0 == passWord.Length) || (passWord.Length > 25)) { System.Diagnostics.Trace.WriteLine("[ValidateUser] Input validation of passWord failed."); return false; } try { // Consult with your SQL Server administrator for an appropriate connection // string to use to connect to your local SQL Server. conn = new SqlConnection("databaseConnect"); conn.Open(); // Create SqlCommand to select pwd field from users table given supplied userName. cmd = new SqlCommand("Select Password from Users where User=@userName", conn); cmd.Parameters.Add("@userName", System.Data.SqlDbType.VarChar, 25); cmd.Parameters["@userName"].Value = userName; // Execute command and fetch pwd field into lookupPassword string. lookupPassword = (string)cmd.ExecuteScalar(); // Cleanup command and connection objects. cmd.Dispose(); conn.Dispose(); } catch (Exception ex) { // Add error handling here for debugging. // This error message should not be sent back to the caller. System.Diagnostics.Trace.WriteLine("[ValidateUser] Exception" + ex.Message); } // If no password found, return false. if (null == lookupPassword) { // You could write failed login attempts here to event log for additional security. return false; } // Compare lookupPassword and input passWord, using a case-sensitive comparison. return (0 == string.Compare(lookupPassword, passWord, false)); } private void cmdLogin_ServerClick(object sender, System.EventArgs e) { if (ValidateUser(txtUserName.Value, txtUserPass.Value)) { FormsAuthenticationTicket tkt; string cookiestr; HttpCookie ck; tkt = new FormsAuthenticationTicket(1, txtUserName.Value, DateTime.Now, DateTime.Now.AddMinutes(30), chkPersistCookie.Checked,"your custom data"); cookiestr = FormsAuthentication.Encrypt(tkt); ck = new HttpCookie(FormsAuthentication.FormsCookieName, cookiestr); if (chkPersistCookie.Checked) ck.Expires = tkt.Expiration; ck.Path = FormsAuthentication.FormsCookiePath; Response.Cookies.Add(ck); string strRedirect; strRedirect = Request["ReturnUrl"]; if (strRedirect == null) strRedirect ="default.aspx"; Response.Redirect(strRedirect, true); } else Response.Redirect("1.0.0.0_LoginScreen.aspx", true); } } } |
现在,我已经测试了连接字符串,它可以工作了。它正在连接到SQL Server数据库中的一个表,该数据库包含3列用户、密码和用户角色。现在我在表中只有一个测试条目,如图所示。
但是,当我运行应用程序并在"txtUserName"中输入"test",在"txtUserPass"中输入"password"并单击"submit"时,它将重定向回登录页面,这意味着它将返回"if(validateuser(txtUserName.value,txtUserPass.value))"的false。
如果有人能帮我解决这个错误,我会感激的。谢谢你的帮助。:)
this is my first time trying to do authentication so I'm not totally
sure how to get the return value by using the breakpoint.
在连接到SQL Server之前,您需要使用硬编码的用户名和密码进行测试。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | protected void cmdLogin_ServerClick(object sender, System.EventArgs e) { if (String.Equals(txtUserName.Value,"johndoe", StringComparison.InvariantCultureIgnoreCase) && String.Equals(txtUserPass.Value,"123456", StringComparison.InvariantCultureIgnoreCase)) { var roles = new[] {"Administrators"}; var ticket = new FormsAuthenticationTicket(1, txtUserName.Value, DateTime.Now, DateTime.Now.AddMinutes(30), chkPersistCookie.Checked, string.Join(",", roles), FormsAuthentication.FormsCookiePath); var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(ticket)); if (chkPersistCookie.Checked) cookie.Expires = ticket.Expiration; Response.Cookies.Add(cookie); string returnUrl = Request["ReturnUrl"]; if (returnUrl == null) returnUrl ="default.aspx"; Response.Redirect(returnUrl, true); } else Response.Redirect("1.0.0.0_LoginScreen.aspx", true); } |
如何创建主体对象
当一个经过身份验证的用户被请求一个页面时,您需要从cookie中检索身份验证票据,并创建一个主体对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // Global.asax.cs public class Global : HttpApplication { void Application_AuthenticateRequest(object sender, EventArgs e) { HttpCookie decryptedCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName]; if (decryptedCookie != null) { FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(decryptedCookie.Value); string[] roles = ticket.UserData.Split(new[] {","}, StringSplitOptions.RemoveEmptyEntries); var identity = new GenericIdentity(ticket.Name); var principal = new GenericPrincipal(identity, roles); HttpContext.Current.User = principal; Thread.CurrentPrincipal = HttpContext.Current.User; } } } |
用法
1 2 3 4 5 6 7 8 9 10 11 12 | public partial class _Default : Page { protected void Page_Load(object sender, EventArgs e) { if (User.Identity.IsAuthenticated) { string username = User.Identity.Name; bool isAdministrator = User.IsInRole("Administrators"); } } } |