7

C# で VS2010 を使用して WebForms Web アプリケーションを開発しています。カスタム ログイン アプローチを使用してユーザーを認証していますが、メンバーシップ フレームワークは使用したくありません。ユーザーのログイン後、ユーザー データを userId、ユーザー名、姓、電子メールなどとして保存したいので、すべてのページでユーザー セッション中にそれらにアクセスできます。

どうやってやるの?UserDataのプロパティにユーザーデータを保存したくありませんFormsAuthenticationTicket

私はこのアプローチを見つけました:セッションにユーザーデータを保存するか、カスタムプロファイルプロバイダーを使用する必要がありますか? 、しかし、私はそれを実装する方法を理解していません。

私はいくつかの質問があります:
1) 私が使用する db の資格情報を確認した後、ユーザーを認証するためのログイン ページで: FormsAuthentication.SetAuthCookie(txtUserName.Value, true); 現在、私のデフォルトページには次のようなものがあります:
FormsAuthenticationTicket ticket = ((FormsIdentity)(User.Identity)).Ticket; そして、私は ticket.Name を使用してユーザー名を表示します。それが正しいか?Thread.CurrentPrincipal.Identity.Name を使用してスレッドについて話すのはなぜですか?
2) global.asax ファイルに次のコードを記述して、ユーザー ロールを読み取り、それらを HttpContext に格納します。

void Application_AuthenticateRequest(オブジェクト送信者, EventArgs e) {

    if (Request.IsAuthenticated) {
        SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["SQLConnStr"].ConnectionString);
        conn.Open();

        SqlCommand cmd = new SqlCommand("SELECT Gruppi.Name FROM Ruoli INNER JOIN Gruppi ON Ruoli.GroupID = Gruppi.GroupID INNER JOIN Utenti ON Ruoli.UserID = Utenti.UserID AND Utenti.Username=@UserName", conn);      
        cmd.Parameters.AddWithValue("@UserName", User.Identity.Name);
        SqlDataReader reader = cmd.ExecuteReader();
        ArrayList rolelist = new ArrayList();         
        while (reader.Read()){
            rolelist.Add(reader["Name"]);
        }
          //  roleList.Add(reader("Name"))           
        string[] roleListArray = (string[])rolelist.ToArray(typeof(string));
        HttpContext.Current.User = new GenericPrincipal(User.Identity, roleListArray);

        reader.Close();
        conn.Close();
    }

}

login.aspx ページではなく、global.asax ファイルから書き込んだように、ユーザー データをセッションに保存できますか?

4

3 に答える 3

5

デバッグを容易にするために、ここで説明するセッション ファサード デザイン パターンを使用することをお勧めします。これにより、オブジェクトを使用して現在のユーザーのデータをHttpContext.Current.Sessionより整理された方法で保存できます。

たとえば、 との間でSessionFacade.cs渡される値の処理を担当するファイル (例: ) がありSessionます。あなたの場合、次のようになります。

public static class SessionFacade
{
    public static int UserId
    {
        get {
            if (HttpContext.Current.Session["UserId"] == null)
                HttpContext.Current.Session["UserId"] = 0;
            return (int)HttpContext.Current.Session["UserId"];
        }
        set {
            HttpContext.Current.Session["UserId"] = value;
        }
    }
    // ... and so on for your other variables
}

次に、コードの別の場所で、資格情報が問題ないことを確認したら、次のことができます...

if (credentialsAreOk) {
    SessionFacade.UserId = /* insert ID here */
    // ...
}

...手動で値を Session オブジェクトに割り当てる代わりに。これにより、変数Sessionが正しい型になり、デバッグ中に追跡しやすくなります。次に、プログラムのどこからでも UserId を取得するには、SessionFacade.UserId.

(はい、そのスニペットは Eduard の回答からのものでした。WebForms がどのように機能するかについて有益であるため、その回答を調べる必要がありSessionます。コードでオブジェクトを手動で呼び出すと非常に面倒になる可能性があり、Session Facade がそのプロセスを行うことに注意してください。クリーナー)

于 2013-08-06T17:03:41.900 に答える
3

「C# の VS2010 による Web アプリケーション」で ASP.NET (MVC またはクラシック) について話し、「カスタム ログイン アプローチ」でFormsAuthenticationを参照している場合、後で必要な情報を保存するだけで済みます。ログイン時の情報をSessionオブジェクトに渡します。

ASP.NET Classic を使用していて、ログイン ページがあるとします。

ここに画像の説明を入力

ユーザー名とパスワードの2つの入力と、「ログイン」というタイトルの送信ボタンがあります

ここに画像の説明を入力

ボタンの (サーバー側) OnClick イベント ハンドラーでは、次のようにする必要があります。

public partial class Login : System.Web.UI.Page {

    protected void Page_Load(object sender, EventArgs e) {

    }

    private bool CheckUserPass(string username, string password) {
        // access DB or some other form of storage service
        return true;
    }

    protected void buttonLogin_Click(object sender, EventArgs e) {

        bool credentialsAreOk = this.CheckUserPass(
            this.textBoxUsername.Text,
            this.textBoxPassword.Text
        );

        if (credentialsAreOk) {
            this.Session["EMAIL_ADDRESS"] = "SomeEmail@SomeEmailProvider.com";
            this.Session["OTHER_INFORMATION_KEY"] = "Some other stuff which you have access to during the login process";
            this.Session["TIME_OF_LOGIN"] = DateTime.UtcNow;

            FormsAuthentication.RedirectFromLoginPage(this.textBoxUsername.Text, createPersistentCookie: false);
        }

    }

}    

つまり、FormsAuthentication を使用している場合、現在のセッションを非認証から認証済みに変換する必要があることを FormsAuthentication システムに伝えるのと同じ方法で、ユーザー名をセッションに保存できます。

FormsAuthentication.RedirectFromLoginPage(this.textBoxUsername.Text, createPersistentCookie: false);

一方、他の情報は Session オブジェクトに配置できます (キーと値のペアを Dictionary に追加するのと同じように):

this.Session["TIME_OF_LOGIN"] = DateTime.UtcNow;

後で同じ情報にアクセスする方法は明らかですが (それぞれのユーザーに対して):

DateTime whenDidILogin = (DateTime) this.Session["TIME_OF_LOGIN"];
// this line of code can be used in any other page
// at any later time - it's like you have a global set of variables
// which exist for each and every distinct session you might have

ユーザー名 (他の例のように Session オブジェクトに明示的に配置されていない場合) は、次のようにThread.CurrentPrincipal静的プロパティを使用してアクセスできることに注意してください。

using System.Threading;

public void SomeWhereInYourApp() {
    bool wasIAuthenticated = Thread.CurrentPrincipal.Identity.IsAuthenticated;
    string whatIsMyUsername = Thread.CurrentPrincipal.Identity.Name;

    // do something with that information
}
于 2013-08-06T16:28:05.050 に答える
0

メンバーシッププロバイダーは、データの保存と認証の目的で役立ちます。このようなもの:-

Session["UserName"] = Membership.GetUser().UserName
于 2013-08-06T16:14:41.083 に答える