0

ASP.NET C#Webサイトで、セッションを使用して、セッションが有効な間、ユーザーがログインして安全なページ内を移動できるようにしようとしています。何らかの理由でタイムアウトまたはサインアウトした場合は、ランディングページにリダイレクトされます。現在、このサイトでは一度に1人のユーザーしかログインできません。セッション情報が正しく保存されていないようですが、どこで、なぜ発生するのかわかりません。別のブラウザを使用してページにアクセスすると、セッションから情報(ユーザー名など)を取得しているため、コードが認識していないことがわかります。

複数の有効なユーザーが同時にログインできるようにし、その間、お互いに悪影響を与えないようにしたい。以下に投稿するコードサンプル以外の情報が必要な場合は、お問い合わせください。

私のログインページ:

//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# プログラミング ガイド)を参照してください。

静的コンストラクターは 1 回だけ呼び出され、静的クラスは、プログラムが存在するアプリケーション ドメインの存続​​期間中、メモリ内に残ります。

コード-

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

アプリケーションの存続期間中、同じ SessionID を返します。

他の投稿者と同様に、ASP.NET 組み込みのメンバーシップ プロバイダーを使用することを強くお勧めします。これは、独自のメンバーシップ プロバイダーを試して発明するのではなく、より安全で、より広く理解され、サポートされ、保守が容易で、拡張性が高くなります。

于 2013-01-17T21:35:21.137 に答える