以编程方式将用户登录到 asp.net 成员资格和角色

本文关键字:成员 net 角色 asp 方式 编程 用户 登录 | 更新日期: 2023-09-27 18:34:40

我正在开发一个 Asp.Net 4.0 Web应用程序,该应用程序正在使用 Asp.Net 的成员资格和角色功能。

在应用程序中,将有三个角色可以访问登录页面

,一个角色无法访问登录页面。

它应该工作的方式如下。

后端用户(在三个特权角色之一中(创建一个用户。在代码中,这是以编程方式完成的,而不是使用"注册用户"页。创建用户时,用户将添加到非特权角色,为清楚起见,该角色称为访问者角色。

然后,后端用户为新用户创建一个链接,其形式为 https://www.example.com?link=cc82ae24-df47-4dbf-9440-1a6923945cf2

访问链接时,应用程序将找到与查询字符串关联的用户,获取用户名和密码(经过适当的哈希处理和加盐处理(并将用户登录。

这就是我要解开的地方。到目前为止,用户创建工作正常,基于查询字符串值的数据库查询正在完成其工作并返回相关信息,除了实际登录之外,一切似乎都运行良好。似乎没有一种明确的方法以编程方式登录用户,而无需经历让用户自己登录的严格操作,我已经明确告诉我要避免这种情况。

这是我的代码,"pers"对象是一个类,当它们登陆链接的默认页面时,它会从数据库填充:

protected void LogUserIn(string p)
{
    SqlConnection conn = UtilityMethods.GetConnection();
    Guid par = Guid.Parse(p);
    BioProspect pers= new BioProspect(conn);
    pers.FillDetailsFromDb(par);
    testlable.Text = pers.ToString();
    Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
    try
    {
        if (Membership.ValidateUser(pers.Email, pers.Pword))
        {
            FormsAuthentication.SetAuthCookie(pers.Email, true);
            Response.Redirect(Request.Url.Scheme + "://" + Request.Url.Host + "/About.aspx");
            testlable.Text = "Logged in!";
        }
        else
        {
            throw new Exception("Something went wrong");
        }
    }
    catch (Exception ex)
    {
        StringBuilder sb = new StringBuilder();
        foreach (DictionaryEntry d in ex.Data)
        {
            sb.Append(d.Key.ToString());
            sb.Append(": ");
            sb.Append(d.Value.ToString());
            sb.Append("'r'n");
        }
        AMessage(sb.ToString());
    }
}

现在,我已经根据数据库表本身检查了用户名和密码的值,并且都是正确的。我知道存储在 aspnet 表中的密码已经过加盐和哈希处理,因此我正在检查我创建的临时表中的值以保存明文。没错。此外,在上面的代码中,FormsAuthentication.SetAuthCookie 方法要求输入用户名和密码 - 在本例中,用户名是电子邮件地址。在调试期间检查此信息时也是正确的。

我应该指出,我们发送的链接几乎是一次性链接。每次与该特定用户相关的更改时,link 参数的值都会更改,旧链接将完全无用。他们将被重定向到的页面将包含与该特定用户直接相关的文档,而不是与其他人直接相关的文档。

但是,我们仍然需要 Asp.Net 成员资格、配置文件和角色框架的好处,因为"访问者"很可能有几个链接发送给他们,随着时间的推移,不同的文档和文档版本会添加和更改。

谁能想到更好的方法?到目前为止,我已经在这里和这里查看了大多数相关条目,但它们似乎都有些不完整。

编辑

我似乎至少部分解决了这个问题,使用从这里接受的答案中收集的信息

从本质上讲,问题是我的 web.config 成员资格部分需要被告知使用哪种哈希算法。目前,我不知道默认的是什么,如果有的话,但添加

<membership hashAlgorithmType="SHA1">

到 web.config 至少允许我登录在添加上述行后创建的用户。下一步是让我了解为什么我无法让其他用户登录。

但是,我仍然按照Joe的建议获得ThreadAbortException,我现在正忙于解决该问题。

以编程方式将用户登录到 asp.net 成员资格和角色

我不确定我是否完全理解您的问题,但是调用FormsAuthentication.SetAuthCookie基本上会以编程方式登录用户。

此外,在上面的代码中,FormsAuthentication.SetAuthCookie方法要求输入用户名和密码。

不,SetAuthCookie需要用户名,但不需要密码。

在示例代码中,对 Response.Redirect 的调用将抛出一个 ThreadAbortException ,以便执行 catch 块。 也许这会让你感到困惑。

回应评论:

从本质上讲,我遇到的问题是用户似乎没有登录。窗体身份验证方法返回 false

上面的代码中没有FormsAuthenticate方法。

话虽如此,我不明白为什么在这种情况下尝试对用户(Membership.ValidateUser(进行身份验证。 我本以为您会想要找到与查询字符串关联的用户名,然后只需调用FormsAuthentication.SetAuthCookie即可登录。

我知道存储在 aspnet 表中的密码已被加盐 和散列,所以我正在检查我创建的临时表中的值 以保存明文。没错。此外,在上面的代码中, FormsAuthentication.SetAuthCookie 方法要求输入用户名 和密码 - 在本例中,用户名是电子邮件地址。 在调试期间检查此信息时也是正确的。

请不要以纯文本形式存储密码或任何密码。

从本质上讲,我遇到的问题是用户似乎没有 正在登录。方法返回 false。

您是否 100% 确定这根本不是 cookie 问题?

似乎您应该能够提供存储的密码哈希和用户名并登录所述用户帐户。 只需覆盖散列"密码"的方法,而是将受保护的密码转发到身份验证系统。