0

在我的 ASP.NET C# 网站中,我尝试使用会话来允许用户在会话有效时登录并浏览安全页面。如果出于某种原因他们超时或退出,他们将被重定向到登录页面。目前,该站点一次只允许一个用户登录。显然会话信息存储不正确,但我不明白发生这种情况的位置或原因。如果您使用其他浏览器访问该页面,您会看到代码从会话中提取出它不应该知道的信息(例如用户名)。

我希望允许多个有效用户同时登录,并且这样做不会对彼此产生不利影响。如果您需要比我在下面发布的代码示例更多的信息,请询问。

我的登录页面:

//Login.ascx.cs
...
private void Login_Click(object sender, EventArgs e)
{
    if (sender == null || e == null)
    {
        throw new ArgumentNullException("Null Exception: Login_Click");
    }

    User user = new User();            
    user.Login(_username.Text, _password.Text);           

    if (user.IsValid() && user.GetIsUser() != false)
    {
        user.Save();
                Session["Username"] = _username.Text;
                Response.Redirect("Secure/Default.aspx");
    }
    else
    {
        DisplayErrors(user._validationErrors);
    }
    _errors.Text = errorMessage;
}

欢迎页面(用户看到的第一个安全页面)

private void Page_Load(object sender, System.EventArgs e)
{
   Business.User user      = new Business.User();

   _labelUsername.Text     = MySession.Current.Username;
   _labelCompanyId.Text    = MySession.Current.CompanyId;

   redirectLogin    = "../Default.aspx";

   //redirect if any conditions fail for user validation.
   if (sessionKey != MySession.GetSessionId() || (string)Session["Username"] != _labelUsername.Text)
   {
      Response.Redirect(redirectLogin);
   }
   else
   {
      Debug.WriteLine("Welcome SUCCESS: " +  _labelUsername.Text);
      Debug.WriteLine("Welcome " + sessionKey);
   }          
}

最后是包含 SQL 查询的用户页面

public static string    dataUsername;
public static string    dataCompanyId;

private const string    _getUserByUsernameQuery = 
@"SELECT [User].[username], [Company].[name]
FROM [User] WITH (NOLOCK) INNER JOIN [Company] WITH (NOLOCK)
ON [User].[companyId] = [Company].[id]
WHERE [User].[username] = @username  AND [User].[password] = @password";

private string          _username;
private string          _companyid;

public User(){}

public void Login (string username, string password)
{
  using (SqlConnection connection = new SqlConnection(SQLConfiguration.ConnectionString))
  {
    SqlCommand command = new SqlCommand(_getUserByUsernameQuery, connection);
    command.Parameters.AddWithValue("@username", username);
    command.Parameters.AddWithValue("@password", password);

    connection.Open();

    using (SqlDataReader reader = command.ExecuteReader())
    {
      if (reader.Read())
      {
        Username        = Convert.ToString(reader["username"]);
        CompanyId       = Convert.ToString(reader["name"]);
        dataUsername    = Username;
        dataCompanyId   = CompanyId;
      }
    }
  }
}

#region Properties
public string Username
{
  get{ return _username; }
  set{ _username = value;}
}
public string CompanyId
{
  get{ return _companyid;}
  set{ _companyid = value;}
}
#endregion

编辑:针对一些问题:

//in the first accessed page for secure users, before 'Page_load'
public static string sessionKey 
{ 
   get 
   {
      return MySession.GetSessionId(); 
   }  
}
...
//in my 'MySession' class
public static string GetSessionId()
{
   return System.Web.HttpContext.Current.Session.SessionID;
}
4

2 回答 2

2

请参阅静态类和静态类成员(C# 编程指南)

静态构造函数只被调用一次,静态类在程序所在的应用程序域的整个生命周期内都保留在内存中。

编码-

public static string GetSessionId()
{
   return System.Web.HttpContext.Current.Session.SessionID;
}

将在应用程序的生命周期内返回相同的 SessionID。

像其他海报一样,我强烈建议您使用 ASP.NET 内置的会员提供程序,而不是尝试自己发明,这将更安全、更广泛理解并因此受到支持、更易于维护和更可扩展。

于 2013-01-17T21:35:21.137 回答
0

只需使用 ASP.NET 表单身份验证。我敢打赌所有匿名用户都在共享同一个会话对象。如果某些东西已经存在,您可以将其连接到您自己的身份验证方案中。(例如,数据库或文件中的密码)

于 2013-01-17T20:52:35.550 回答