Have a few questions onf ASP.NET Membership

I just have a few functional questions on asp.net membership provider. I would like to setup my application to have my admins create the userid, email address, and roles. Leave the account inactive, then send the user a email to the registration completion page where they will select there security question provide the answer, enter their password and confirm it. Then on completion the data is saved and the id is activated. Can this be done? And if so where would I need to begin to modify the current processing of the creatuser function?

Jeff
woodjeAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

techExtremeCommented:
Hello,
for your case, you need to implement a custom membership provider.
Go thru this link: http://msdn.microsoft.com/en-us/library/f1kyba5e.aspx
It explains what is to be done.
Let me know incase of queries.
Happy Coding!
0
Tapan PattanaikSenior EngineerCommented:
hi woodje,

                Check these links.

How To: Use Membership in ASP.NET 2.0:

http://msdn.microsoft.com/en-us/library/ms998347.aspx

Examining ASP.NET 2.0's Membership, Roles, and Profile :

http://www.4guysfromrolla.com/articles/120705-1.aspx

Membership and Role Providers in ASP.NET 2.0:

http://www.odetocode.com/Articles/427.aspx

http://weblogs.asp.net/scottgu/archive/2006/02/24/ASP.NET-2.0-Membership_2C00_-Roles_2C00_-Forms-Authentication_2C00_-and-Security-Resources-.aspx
0
Tapan PattanaikSenior EngineerCommented:
0
Learn Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

guru_samiCommented:
This can be done but requires a bit of basic understanding on setting up membership and roles providers. Which you can get from previous links. After following them..

1: Modify the CreateUserWizard to not show PasswordQuestion and Answer.
in web.config set requiresQuestionAndAnswer="false" in membership settings.
2: Add wizard step in CUW for assigning Roles.
Get some idea here: http://weblogs.asp.net/scottgu/archive/2005/10/18/427754.aspx
3: Set AutoGeneratePassword property of CUW = true. Set the MailDefinition Property to appropriate values. Then this password will be / should be sent to user via email and the login Link to FirstTimeUserLoginPage that has UserID.
4: Also set  property DisableCreatedUser = false.
5: Design a FirstTime User page....that takes username, Password,New Password, PasswordQuestion, PasswordAnswer.
In the code behind you should perform this step by step and atomic....
a. Using username+Password make sure user is valid....
if so then Using API methods... change Reset UserPassword, set PasswordQuestionAnswer and then Approve the User. Then Login the user or send the user to your general login page where he/she can login using new password.

What you want is doable ..but its not that easy to explain in writing ...
HTH
0
woodjeAuthor Commented:
guru_sami,

Thanks for the response. I have been reviewing all the links and your comment. I have the CUW and the assigning Roles complete. And the DisableCreatedUser = false. The problem I have is I don't want to set a password at all. I want to just set the userid, email, and roles. Then send a email to a registration page. When they enter the userid it will check to see if it exsists and that the id is not active. If so then it will then go to a modifed create user wizard to have them select a secutity question and enter an answer. Enter a password and then confirm the password. And enter some additional information on name and supervisor. Then if all validation is completed true to save the data and enable the userid. Then redirect to the "~/login.aspx" page. From what I have read it seems like all can be done except getting around the password. With membership the minimum you can have in account setup is userid, password. So please let me know if I can't get around that. If so I will look at your path and see if I can get them to except those changes.

Jeff
0
guru_samiCommented:
I have a suggestion on that:
1: Setting AutoGeneratePassword property of CUW = true. Let the password being generated. So Admin does not need to set password explicitly.
2: Since you are setting DisableCreatedUser=True..it is user is not active. So there is no way for user to login.
3: Do not send user the Password in the Email that is sent once user is Created. Just send them they Username and the link to activate the account. This can be easily done using MailDefinition/BodyFileName
and OnSendingEmail Event of CUW.
Check this:
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.createuserwizard.onsendingmail.aspx
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.createuserwizard.maildefinition.aspx

So ideally there will be a Password in DB but now it is not know to the admin or the user (assuming its not in ClearFormat)

Try and see if that meets your requirements.
0
woodjeAuthor Commented:
Thanks for the response. I am able to create the user and assign their roles with a modified cuw. And it is generating an email now that has the userid and the auto generated password that will send to the user.  My thoughts now are to have the email modified to have the url it is passing have the userid so it will take the user to a new page in the public directory that will have the user complete another cuw that will have them set a new password, select a security question, and answer. Part of the check when they go to the new page is that the userid is not active. Then once they complete all the info the table is updated and the id is activated.  Any ideas how I can setup the sql data source to take the userid from the email and the email address from the table so the cuw can complete its checks?
0
guru_samiCommented:
Here is a sample that sends user activation Email and then Activate it:
http://www.4guysfromrolla.com/articles/062508-1.aspx

Hope that will help you move forward.
0
woodjeAuthor Commented:
guru_sami,

Thanks for the response this has helped me a lot. Maybe you can get me over the last hump. I have the email it takes me to my cuw. I call for the cuw to GetUser(userInfo) event. I need to have the cuw populate the username with the UserId and the Email with the Email. I have made these fields read-only but I need to populate the data.
0
guru_samiCommented:
when you say userId ... do you mean thta 16-digit UniqueIdentifier or the UserName?
Also do you mean you are going to use CreateUserWizard control on this user activation Page?
If YES, then make sure if you hit Create button, you might get DuplicateUser error message. Hope you are handling that scenario.

Below is sample code:

 string userId = GetFromyour Email Link;
        MembershipUser user = Membership.GetUser(userId);
        CreateUserWizard1.UserName = user.UserName;
        CreateUserWizard1.Email = user.Email;

Open in new window

0
woodjeAuthor Commented:
Not yet I haven't but I will. Iam having problems getting the code to populate the right values when the page loads. Here is the code I have right now.

Partial Class public_register_user
    Inherits System.Web.UI.Page
 
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If String.IsNullOrEmpty(Request.QueryString("ID")) OrElse Not Regex.IsMatch(Request.QueryString("ID"), "[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}") Then
            Dim ErrorMessage As Literal = Nothing
            ErrorMessage.Text = "An invalid ID value was passed in through the querystring."
        Else
            'ID exists and is kosher, see if this user is already approved
            'Get the ID sent in the querystring
            Dim userId As Guid = New Guid(Request.QueryString("ID"))
 
            'Get information about the user
            Dim userInfo As MembershipUser = Membership.GetUser(userId)
            If userInfo Is Nothing Then
                'Could not find user!
                Dim ErrorMessage As Literal = Nothing
                ErrorMessage.Text = "The user account could not be found in the membership database."
            End If
        End If
    End Sub
 
    Protected Sub CreateUserWizard1_CreatedUser(ByVal sender As Object, ByVal e As System.EventArgs) Handles CreateUserWizard1.CreatedUser
        Dim userId As Guid = New Guid(Request.QueryString("ID"))
        Dim userInfo As MembershipUser = Membership.GetUser(userId)
        userInfo.IsApproved = True
        Membership.UpdateUser(userInfo)
    End Sub
 
    Protected Sub ContinueButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)
        Response.Redirect("~/login.aspx")
    End Sub
End Class

Open in new window

0
guru_samiCommented:
what is the error?
Also I think you will not be able to Create a User again with the same ID. It will give you error message of Duplicate User. So you will have to create your own CreateUserWizard like display.
0
woodjeAuthor Commented:
Yeah I am running into that. Thought I would give it a try. Guess I will have to abandon that idea. Would you recommend using a wizard control with a sql data source? And if so can I get rid of the step windows? I want it to flow like the cuw.
0
guru_samiCommented:
I should Say CUW will not work so yes you should look into Wizard Control.
You don't have to use SQLDatasoure as well but just write a query to do your DB work on ButtonClick.

And if so can I get rid of the step windows?
Not sure what you mean by that.
0
woodjeAuthor Commented:
With the wizard control as you name your steps it places those names to the left and they are clickable link to move back and forth if the wizard was several steps. I don't want this left had nav function I just want it to flow from step one to step two.
0
guru_samiCommented:
I think there will be setting where you can force Wizard control to flow in one direction....which I am not sure of...
Second option is MultiView control. where you Activate the appropriate View(that will act as a step) as per your need.
0
woodjeAuthor Commented:
guru_sami,

Thanks for all your help with this. I am looking into the wizard option. I have found the setting to remove the menu on the right. I think I have been working on this process to long that it is confusing me when it shouldn't. So please keep me honest here. I will be looking on the next step vb code to do an update to the aspnet_Membership tables following fields:

Password
PasswordQuestion
PasswordAnswer
IsApproved

The fields from the form register_user.aspx are as follows:
control=Wizard1
fields :
textbox = Password
DropDownList = sec_ques_1_list
textbox = Answer

Now I will need to run the update and set the IsApproved = True

I have a sqlclient connection string setup in my web.config file called fss_cao_ConnectionString

and the wizard control is = ContinueButton_Click

So now I am fuzzy on how to setup the vb to pull the GUID from the URL as a paramater in the update query. And the basic structure of the code in general. Do you have any suggestions for me?
0
guru_samiCommented:
This is what the code I see you pasted before:

Dim userId As Guid = New Guid(Request.QueryString("ID"))
Dim userInfo As MembershipUser = Membership.GetUser(userId)
userInfo.IsApproved = True
Membership.UpdateUser(userInfo)

So to Activate User account part you already have.

For Password setting and Ques/Answer you will be using Membersihp API as well. But to help you on that I will need the membership settings from your web.config.
0
woodjeAuthor Commented:
I think this is what you are asking for? Let me know if you need anything else.


<membership defaultProvider="fss_caoMembershipProvider">
      <providers>
        <add connectionStringName="fss_cao_SqlServer" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" applicationName="FinanceUnifiedDatabase" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="3" minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" passwordStrengthRegularExpression="" name="fss_caoMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
      </providers>
    </membership>
    <profile>
      <providers>
        <add name="fss_caoProfileProvider" connectionStringName="fss_cao_SqlServer" applicationName="/" type="System.Web.Profile.SqlProfileProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
      </providers>
    </profile>
    <roleManager enabled="true" defaultProvider="fss_caoRoleProvider">
      <providers>
        <add connectionStringName="fss_cao_SqlServer" applicationName="FinanceUnifiedDatabase" name="fss_caoRoleProvider" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
      </providers>
    </roleManager>
    <siteMap defaultProvider="XmlSiteMapProvider" enabled="true">
      <providers>
        <add name="XmlSiteMapProvider" description="Default SiteMap provider." type="System.Web.XmlSiteMapProvider" siteMapFile="Web.sitemap" securityTrimmingEnabled="true"/>
      </providers>
    </siteMap>
 
<machineKey decryption="AES" validation="SHA1" decryptionKey="52A52F89D307B288A9C835F6CB19FBDDDDEBA5D1E3EDC672D4BCD5187CDB4831" validationKey="C1DEE58DA256BAA6E9952D93C09AEB7B3E6E981D4764C3A95E6EEEA4965E4855"/>

Open in new window

0
guru_samiCommented:
Alrite so here is what I think you should do:

1: Find password Textbox,Question DropDownList, and Answer Textbox like below inside your wizard Control.
2: Get corresponding values from those control
3: Get current user object using UserId from QueryString
4: Call Membership API's ChangePassword to change user password to new password
5: Call Membership API's ChangePasswordQuestionAndAnswer
6: Set IsApproved for the user
7: Update the user

Hope that will give you idea.

'Step 1 
Dim tbPassword As TextBox = DirectCast(Wizard1.FindControl("txtPassword"), TextBox) 
Dim ddlQuestion As DropDownList = DirectCast(Wizard1.FindControl("QuestionDDL"), DropDownList) 
Dim tbAnswer As TextBox = DirectCast(Wizard1.FindControl("txtAnswer"), TextBox) 
 
'Step 2 
Dim newPassword As String = tbPassword.Text 
Dim pwdQuestion As String = ddlQuestion.SelectedValue.ToString() 
Dim pwdAnswer As String = tbAnswer.Text 
 
'Step 3 
Dim userId As New Guid(Request.QueryString("ID")) 
Dim user As MembershipUser = Membership.GetUser(userId) 
 
'Step 4 
user.ChangePassword(user.ResetPassword(), newPassword) 
 
'Step 5 
user.ChangePasswordQuestionAndAnswer(newPassword, pwdQuestion, pwdAnswer) 
 
'Step 6 
user.IsApproved = True 
 
'Step 7 
Membership.UpdateUser(user) 

Open in new window

0
woodjeAuthor Commented:
I have updated my code to what you sent me. However I do have a an error showing in my data. It reads "  'ChangePassword' is not a member of 'System.Security.Principle.IPrincipal'  " and  "  'ChangePasswordQuestionAndAnswer' is not a member of 'System.Security.Principle.IPrincipal'  " am I missing importing a class at the top of my VB class?
0
guru_samiCommented:
I see thats because of "user" and "User" conflict
make sure "user" is lower case or change all "user" reference to"_user"
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
woodjeAuthor Commented:
Thanks for the quick response. I had worked with it as well and finally got it to work. I changed the user to userInfo and it worked. I am enclosing the completed code here as well so it will be available for others. Thanks again for all your help.
 Protected Sub Wizard1_FinishButtonClick(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.WizardNavigationEventArgs) Handles Wizard1.FinishButtonClick
        Response.Redirect("~/login.aspx")
    End Sub
    Protected Sub Wizard1_NextButtonClick(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.WizardNavigationEventArgs) Handles Wizard1.NextButtonClick
        Dim tbPassword As TextBox = DirectCast(Wizard1.FindControl("Password"), TextBox)
        Dim ddlQuestion As DropDownList = DirectCast(Wizard1.FindControl("sec_ques_1_list"), DropDownList)
        Dim tbAnswer As TextBox = DirectCast(Wizard1.FindControl("Answer"), TextBox)
 
        Dim newPassword As String = tbPassword.Text
        Dim pwdQuestion As String = ddlQuestion.SelectedValue.ToString()
        Dim pwdAnswer As String = tbAnswer.Text
 
        Dim userId As Guid = New Guid(Request.QueryString("ID"))
        Dim userInfo As MembershipUser = Membership.GetUser(userId)
 
        userInfo.ChangePassword(userInfo.ResetPassword(), newPassword)
 
        userInfo.ChangePasswordQuestionAndAnswer(newPassword, pwdQuestion, pwdAnswer)
 
        userInfo.IsApproved = True
 
        Membership.UpdateUser(userInfo)
    End Sub

Open in new window

0
woodjeAuthor Commented:
This was long and worth it I cann't thank guru_sami enough. Your the best.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
ASP.NET

From novice to tech pro — start learning today.