简体   繁体   English

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

[英]Programmatically log a user in to asp.net membership and roles?

I'm working on an Asp.Net 4.0 web application which is using the Membership and Roles features of Asp.Net. 我正在使用Asp.Net 4.0 Web应用程序,该应用程序使用Asp.Net的Membership和Roles功能。

In the application, there will be three roles which have access to the login page and one role which doesn't. 在应用程序中,将有三个角色可以访问登录页面,而一个角色则没有。

The way it is supposed to work is as follows. 它的工作方式如下。

Back end user (in one of the three privileged roles) creates a user. 后端用户(在三个特权角色之一中)创建用户。 In the code, this is done programmatically rather than using the Register User page. 在代码中,这是以编程方式完成的,而不是使用“注册用户”页面。 When the user is created, they are added to the unprivileged role, which, for the sake of clarity is called the Visitor role. 创建用户时,会将它们添加到非特权角色,为了清楚起见,该角色称为访问者角色。

Back end user then creates a link for the new user which is in the form of https://www.example.com?link=cc82ae24-df47-4dbf-9440-1a6923945cf2 然后,后端用户为新用户创建一个链接,其形式为https://www.example.com?link=cc82ae24-df47-4dbf-9440-1a6923945cf2

When the link is visited, the application will locate the user associated with the query string, get the username and password (which are suitably hashed and salted) and logs the user in. 访问链接时,应用程序将找到与查询字符串关联的用户,获取用户名和密码(适当地进行散列和加盐)并将用户登录。

This is where I'm coming undone. 这是我要撤消的地方。 So far, the user creation is working just fine, the database query based on the value of the query string is doing its job and returning the relevant bits of information, it all seems to be flowing pretty well, except for the actual logging in. There doesn't seem to be a clear method of logging a user in programmatically, without going through the rigmarole of getting the user to log themselves in, which I have been explicitly told to avoid. 到目前为止,用户创建工作正常,基于查询字符串的值的数据库查询正在完成其工作并返回相关的信息位,除了实际登录之外,这一切似乎都很顺利。似乎没有一种明确的方法以编程方式记录用户,而没有经历让用户自己登录的严峻考验,我已明确告知要避免这种情况。

Here is my code, the "pers" object is a class which is populated from the database when they land on the default page of the link: 这是我的代码,“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());
    }
}

Now, I've checked the values of the username and password against the database table itself and it is all correct. 现在,我已经根据数据库表本身检查了用户名和密码的值,这一切都是正确的。 I understand the password stored in the aspnet tables has been salted and hashed, so I'm checking the values in a temporary table I created to hold the clear text. 我知道存储在aspnet表中的密码已经被盐析和散列,所以我正在检查我创建的临时表中的值以保存明文。 It's right. 这是正确的。 In addition, in the code above, the FormsAuthentication.SetAuthCookie method is asking for a username and password - in this instance, the username is the email address. 此外,在上面的代码中,FormsAuthentication.SetAuthCookie方法要求输入用户名和密码 - 在这种情况下,用户名是电子邮件地址。 This information is also correct when inspected during debugging. 在调试期间检查时,此信息也是正确的。

I should point out, the links we are sending are pretty much one time links. 我应该指出,我们发送的链接几乎是一次性链接。 Every time a change is made relevant to that particular user, the value of the link parameter will change and the old link will be come completely useless. 每次更改与特定用户相关时,链接参数的值都将更改,旧链接将完全无用。 The page they will be redirected to will hold documents which are directly relevant to that particular user and to no others. 他们将被重定向到的页面将保存与该特定用户直接相关的文档,而不包含其他文档。

However, we still need the benefits of the Asp.Net Membership, Profiles and Roles framework, since the "Visitor" may well have several links sent to them, with different documents and versions of documents being added and changed over time. 但是,我们仍然需要Asp.Net Membership,Profiles和Roles框架的好处,因为“访问者”可能会向他们发送几个链接,随着时间的推移添加和更改不同的文档和文档版本。

Can anyone think of a better way? 谁能想到更好的方法? I have so far looked at most of the relevant entries here and here but they all seem somewhat incomplete. 到目前为止,我已经在这里这里查看了大部分相关条目,但它们似乎都有点不完整。

EDIT 编辑

I seem to have at least partially resolved this, using information gleaned from the accepted answer here 我似乎至少部分地解决了这个问题,使用从这里接受的答案收集的信息

Essentially, the problem was my web.config membership section needed to be told which hashing algorithm to use. 基本上,问题是我的web.config成员资格部分需要被告知要使用哪种哈希算法。 At the moment, I have no idea what the default one is, if there is one, but adding 目前,我不知道默认的是什么,如果有的话,但是添加

<membership hashAlgorithmType="SHA1">

to the web.config has at least allowed me to log in users created after the above line was added. 到web.config至少允许我登录添加上述行后创建的用户。 The next step is for me to understand why I can't get the other users logged in. 下一步是让我理解为什么我无法让其他用户登录。

I am however still getting a ThreadAbortException as suggested by Joe, which I am now busily working to resolve. 然而,我仍然得到Joe建议的ThreadAbortException,我现在忙于解决。

I'm not sure I completely understand your problem, but a call to FormsAuthentication.SetAuthCookie will essentially log the user in programatically. 我不确定我是否完全理解您的问题,但是对FormsAuthentication.SetAuthCookie的调用本质上将以编程方式记录用户。

In addition, in the code above, the FormsAuthentication.SetAuthCookie method is asking for a username and password 此外,在上面的代码中,FormsAuthentication.SetAuthCookie方法要求输入用户名和密码

No, SetAuthCookie needs a username, but not a password. 不,SetAuthCookie需要用户名,但不需要密码。

In your sample code, the call to Response.Redirect will throw a ThreadAbortException , so that your catch block will execute. 在示例代码中,对Response.Redirect的调用将抛出ThreadAbortException ,以便执行catch块。 Maybe that's confusing you. 也许这让你感到困惑。

In response to comment: 回应评论:

Essentially, the problem I am having is that the user appears not to be getting logged on. 基本上,我遇到的问题是用户似乎没有登录。 The FormsAuthenticate method is returning false FormsAuthenticate方法返回false

There is no FormsAuthenticate method in the above code. 上面的代码中没有FormsAuthenticate方法。

Having said that, I don't see why you're trying to authenticate the user ( Membership.ValidateUser ) in this scenario. 话虽如此,我不明白为什么你在这个场景中试图验证用户( Membership.ValidateUser )。 I'd have thought you'd want to locate the username associated with the querystring, then simply call FormsAuthentication.SetAuthCookie to log him in. 我原本以为你想找到与查询字符串相关联的用户名,然后只需调用FormsAuthentication.SetAuthCookie即可登录。

I understand the password stored in the aspnet tables has been salted and hashed, so I'm checking the values in a temporary table I created to hold the clear text. 我知道存储在aspnet表中的密码已经被盐析和散列,所以我正在检查我创建的临时表中的值以保存明文。 It's right. 这是正确的。 In addition, in the code above, the FormsAuthentication.SetAuthCookie method is asking for a username and password - in this instance, the username is the email address. 此外,在上面的代码中,FormsAuthentication.SetAuthCookie方法要求输入用户名和密码 - 在这种情况下,用户名是电子邮件地址。 This information is also correct when inspected during debugging. 在调试期间检查时,此信息也是正确的。

Please do not store the password or any password in plain text. 请勿以明文形式存储密码或密码。

Essentially, the problem I am having is that the user appears not to be getting logged on. 基本上,我遇到的问题是用户似乎没有登录。 The FormsAuthenticate method is returning false. FormsAuthenticate方法返回false。

Are you 100% sure this simply isn't a cookie issue? 您是否100%确定这不是一个cookie问题?

It seems to be you should be able to provide the stored password hash and the username and log into said user account. 似乎您应该能够提供存储的密码哈希和用户名并登录到所述用户帐户。 Just override the method that hashes the "password" and instead forward the protected password onwards to the authentication system instead. 只需覆盖哈希“密码”的方法,而不是将受保护的密码转发到身份验证系统。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM