This article will discuss in moderate detail the example Firebird Membership/Role/Profile code. If your having problems getting your MemberShip provider connected to your Firebird database then checkout the first part of this article here Firebird MemberShip/Role/Profile Example.
The first part of this article, which discusses setting up the membership database with Firebird, is really the hardest part. Once you have that working the example code is really very simple. I'll go over some of what may be less obvious in the code to help answer some questions people may have. If anyone posts further questions in the future I'll add more detail to address those questions.
1. Forms authentication, Roles and Directories
Example application directory structure:
~\
Guest\
User\
Manager\
Admin\
Example application Web.Config file structure:
~\
<em>Web.config</em> -Forms authentication configuration.
Guest\
<em>Web.config</em> -Accepted Roles(Guest,User,Manager,Admin).
User\
<em>Web.config</em> -Accepted Roles(User,Manager,Admin).
Manager\
<em>Web.config</em> -Accepted Roles(Manager,Admin).
Admin\
<em>Web.config</em> -Accepted Roles(Admin).
Lets take a look at the syntax of the <authorization> tag in each Web.Config file.
<system.web>
<authorization>
<deny users="?"/>
<allow roles="Manager"/>
<allow roles="Admin"/>
<deny users="*"/>
</authorization>
</system.web>
Its important to understand that the authorization rules are handled in the order they appear in the file. Once a rule is processed as true or a match then the checks stop and further rules are ignored.
Example:
2. Overview of Web Pages in the example
The Guest/User/Manager/Admin pages contain no code, just a label with text telling the user they made it to the page. Essentially it just lets you know you had the correct role access to view that page.
3. Guest/User/Manager/Admin Pages
4. Login Page
The Login control contains a property for selecting your MemberShipProvider but since we cleared the default providers and added our own in as the default (see Firebird MemberShip/Role/Profile Example.), we don't need to provide one.
5. Default Page
Two classes are introduced in this code: System.Web.Security.Roles class, and the _Default.Profile property.
System.Web.Security.Roles:
_Default.Profile:
6. NewUser Page
If you prefer to work visually select the CreateUserWizard control and look for the WizardSteps collection property. Click on the button in the property field to get the following:
WizardStep Collection Editor
As you can see I added the "Additional Info" step. You can add your steps visually here. Once your steps are added you will want to customize them with your fields. Close the WizardStep Collection Editor and right-click on the CreateUserWizard control. From the right-click menu select "Show Smart Tag" and you will get the following:
CreateUserWizard Tasks
Notice the steps dropdown list contains all the pages in your wizard. Select the page you want to work on from the list and the view of the NewWizard.aspx in the editor will display that page. Now you can drop down any HTML or asp extended control you want for gathering additional information.
Now lets look at the code we need to make use of the extra information we collected. If you review the NewUser.aspx.cs file you'll see the following code:
protected void CreateUserWizard1_ActiveStepChanged(object sender, EventArgs e) {
if (CreateUserWizard1.ActiveStep == CreateUserWizard1.CompleteStep) {
// Create an empty Profile
ProfileCommon prof =
(ProfileCommon)ProfileCommon.Create(CreateUserWizard1.UserName, true);
WizardStep step = (WizardStep)CreateUserWizard1.WizardSteps[1];
// Save the additional profile info and save
prof.Country = ((TextBox)step.FindControl("txtCountry")).Text;
prof.Age = Int32.Parse(((TextBox)step.FindControl("txtAge")).Text);
prof.Save();
}
}
This function is bound to the ActiveStepChange event on the CreateUserWizard1 control so it will be called each time the user causes the wizard to move to a new page. In this case we only want to do something if the wizard moves to the last page because then we know the user entered something in the "Additional Info" page (assuming some validation is done). Thus we check the ActiveStep to make sure its the CompleteStep which is the last step in our case.
The first thing we need to do is create a new profile for the current user. The profile comes from the ProfileCommon class and the CreateUserWizard1 control has the UserName information. The special Age and Country fields we added in the Web.Config are automatically part of the profile class. All we need to do now is get access to the controls we added to our custom WizardStep. We can grab the WizardStep from the CreateUserWizard1 controls collection and then use the FindControl function on the step to gain access to the txtAge and txtCountry textboxes that were added. Finally just call the ProfileCommon.Save() method and the fields are saved to the database for the current user.
Its possible to handle security is a variety of ways including various levels of manual methods versus completely depending on the built in objects. In the end configuring the default providers to work with the standard Login and CreateUserWizard controls can be somewhat confusing, however once this is done it's generally a lot less effort to use those standard controls. Having said this I would still assume that most large scale web applications use a lot of custom security and will likely move to using more proprietary methods and controls to meet their needs.