7

我正在用 C# 中的 VS2010 开发一个 WebForms Web 应用程序。我使用自定义登录方法对用户进行身份验证,并且我不想使用 Membership 框架。用户登录后,我想将用户数据存储为用户 ID、用户名、姓氏、电子邮件等,以便在所有页面的用户会话期间访问它们。

我怎样才能做到这一点?我不想将用户数据存储UserDataFormsAuthenticationTicket.

我发现了这种方法:我应该在会话中存储用户数据还是使用自定义配置文件提供程序?,但我不明白如何实现它。

我有一些问题:
1)在我使用的数据库上检查凭据后在我的登录页面中对用户进行身份验证: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();
    }

}

我可以像您从我的 global.asax 文件而不是 login.aspx 页面中那样将用户数据存储到会话中吗?

4

3 回答 3

5

为了更容易调试,我建议使用此处描述HttpContext.Current.Session的 Session Facade 设计模式,这将允许您使用对象以更有条理的方式存储当前用户的数据。

例如,将有一个文件(例如,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

如果通过“VS2010 在 C# 中的 Web 应用程序”您正在谈论 ASP.NET(MVC 或 Classic)并且通过“自定义登录方法”您指的是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 对象上(就像您将键值对添加到字典一样):

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 回答