C# 以编程方式将用户登录到asp.net成员身份和角色?

C# 以编程方式将用户登录到asp.net成员身份和角色?,c#,asp.net,asp.net-membership,asp.net-roles,C#,Asp.net,Asp.net Membership,Asp.net Roles,我正在开发一个Asp.NET4.0Web应用程序,它使用Asp.Net的成员资格和角色功能 在应用程序中,将有三个角色可以访问登录页面,一个角色不能访问 它的工作原理如下 后端用户(三个特权角色之一)创建一个用户。在代码中,这是以编程方式完成的,而不是使用Register User页面。当用户被创建时,他们被添加到非特权角色,为了清晰起见,该角色被称为访问者角色 后端用户然后为新用户创建一个链接,其形式为 访问链接时,应用程序将定位与查询字符串关联的用户,获取用户名和密码(经过适当的哈希和盐析)

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

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

它的工作原理如下

后端用户(三个特权角色之一)创建一个用户。在代码中,这是以编程方式完成的,而不是使用Register User页面。当用户被创建时,他们被添加到非特权角色,为了清晰起见,该角色被称为访问者角色

后端用户然后为新用户创建一个链接,其形式为

访问链接时,应用程序将定位与查询字符串关联的用户,获取用户名和密码(经过适当的哈希和盐析),并将用户登录

这就是我要做的。到目前为止,用户创建工作正常,基于查询字符串值的数据库查询正在完成其工作,并返回相关信息位,除了实际登录之外,一切似乎都进行得很顺利。似乎没有一种明确的方法可以通过编程方式登录用户,而不必经历让用户自己登录的繁琐过程,我被明确告知要避免这样做

这是我的代码,“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,我现在正忙于解决这个问题

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

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

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

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

针对评论:


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

上述代码中没有
FormsAuthenticate
方法

话虽如此,我不明白在这种情况下为什么要尝试验证用户(
Membership.ValidateUser
)。我原以为您希望找到与查询字符串关联的用户名,然后只需调用
FormsAuthentication.SetAuthCookie
即可让他登录

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

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


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

你100%确定这不是饼干问题吗


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

嗨,乔,谢谢你的回答。你是对的,它不要求密码,在代码中,我不会传递密码。同样,ThreadAbortException正在发生,但我不得不承认我不明白为什么。在过去,我曾使用这种方法在页面之间重定向,它似乎很有效。尽管如此,try..catch块并没有捕获那个特定的异常。如果我把else挡在外面,try..catch就不行了