Thursday, May 17, 2007

5 Minutes to Forms Authentication

In case you couldn't tell by the last few posts I've made... I really like Forms Authentication! I wasn't very organized and just threw some random posts out here to share some idea's, but sometimes all you need in life is simplicity... so that's what this post will be, a simple Forms Authentication setup.

I recently had to add some type authentication to an existing web application, nothing fancy at all, bare-bones, just a username, a password, and no database connectivity. That's where this post comes in... when all you need is something quick.

We'll cover this in 3 steps. The first is creating your login form, second being your form's code behind, and the third being your web.config setup.

Step 1 - Create Your Web Form

We won't do anything fancy here, all you want is:
  • A Username Textbox
  • A Password Textbox
  • A Button to submit your form
  • A placeholder to display error messages
Let's get to it!

Create a new web form in your project. In our case, we will call our form "login.aspx". Next, go to the login.aspx page and create your form. We want to create elements for each of the items above, so our end result is this:
Please login to use this application
Username:
Password:

Our HTML to create our web form is:


<table>
<tr>
<td colspan="3" id="tdMessage" runat="server"></td>
</tr>
<tr>
<td colspan="3">Please login to use this application</td>
</tr>
<tr>
<td>Username:</td>
<td> </td>
<td><asp:TextBox ID="txtUsername" Runat="server" /></td>
</tr>
<tr>
<td>Password:</td>
<td> </td>
<td>
<asp:TextBox ID="txtPassword" Runat="server"
TextMode="Password" /></td>
</tr>
<tr>
<td colspan="3"><asp:Button ID="btnSub" Runat="server"
Text="Login"></asp:Button></td>
</tr>
</table>

Above we have 5 rows in our table. Row 1 is our TD tag (named tdMessage) that will house our error messages. Row 2 is static text asking the user to log in. Row 3 contains our Username textbox (named txtUserName), Row 4 has our Password textbox (named txtPassword), and Row 5 has our button (named btnSub)That's it, our HTML is built!

Step 2 - Your Code-Behind

Ahh yes, our almighty code-behind... an ASP.NET page is almost useless without it! Our code-behind will remain very simple, as there is no database connectivity needed (as you'll see in step 3)!

For starters, Import the System.Web.Security NameSpace into your login.aspx.vb file:

Imports System.Web.Security

Next, we want to handle all login events in our btnSub Click events. So, within the btnSub click event handler, we place the following code:

If Me.txtUsername.Text = "" Or Me.txtPassword.Text = "" Then
Me.tdMessage.InnerHtml = "<font color=""red"">Please enter proper login
credentials</font><br>"
Else
If FormsAuthentication.Authenticate(Me.txtUsername.Text, Me.txtPassword.Text) Then
FormsAuthentication.RedirectFromLoginPage(Me.txtUsername.Text, True)
Else
Me.tdMessage.InnerHtml = "<font color=""red"">Invalid Login, please try again</font><br>"
End If
End If

Just like everything else in this project, the logic is simple. If a username or password isn't supplied, set the error message to ask for proper login credentials. If both a username and a password are supplied, hand-off the username and password values to the FormsAuthentication.Authenticate function, which returns a true/false value on the credentials. If the username/password authenticates, call RedirectFromLoginPage, which sets the the Forms Authentication cookie, and let's the user go on their merry little way. Otherwise, the login credentials were invalid, so we display an error message asking the user to try again.

Step 3 - Setup Forms Authentication in your Web.Config

Last but not least, we need to setup Forms Authentication in our Web.Config, otherwise all that cool code you wrote above is worthless.

So, open your web.config file in your project, within the system.web node, add the following XML to the Authorization section:

<deny users="?" />

This means that all users who are not authenticated are denied, and therefore are sent to be authenticated.

Secondly, in our Authentication section, add the following XML:

<authentication mode="Forms">
<forms
name="ourFormsAuth"
path="/"
loginUrl="login.aspx"
protection="All"
timeout="30">
<credentials passwordFormat="Clear">
<user name="ourUser" password="ourPassword"/>
</credentials>
</forms>
</authentication>

And that's all it takes! We set our authentication mode to "Forms", meaning that now our app expects a form on the website to authenticate our user. The Forms XML has a name attribute, which is the name of the cookie, the path of where the cookie is stored, the Url of the login form (in our case login.aspx), our protection mode (set to "All" to validate and encrypt the data), and our timeout of the cookie, in minutes). And, if you wish, you can add additional user credentials:

<user name="ourUser1" password="ourPassword1"/>
<user name="ourUser2" password="ourPassword2"/>
<user name="ourUser3" password="ourPassword3"/>

Now when you run your project, a login form will appear, asking you for proper credentials. If you dont enter a proper combination of what you entered in the "credentials" section, it doesn't let you in. As I stated in the beginning of this post... pretty simple!

Labels: , , , ,

Thursday, May 10, 2007

Creating Excel Reports with ASP.NET 2.0

Someone recently stumbled across this article on creating excel reports with ASP.NET 2.0, and they were king enough to forward it my way. It's nice because it makes use of the inherent COM objects from Microsoft Office and Excel, and much of the magic is actualy based around creating your appropriate DataSet, and the Excel piece is kind of just the whipped-cream topping...

Labels: , , , , ,

Sunday, May 06, 2007

Creating a Time control in .NET

Recently I was working on an ASP.NET application that required the end user to enter and submit a time on the web form. I wasn't comfortable leaving it up to a textbox, since I would need both an hour, a minute, and an AM/PM. Leaving this to a textbox entry would require validation for both the user to use a ":" as well as enter an "AM" or "PM" If you ask me... this sounds like a pain in the rear-end.

When I thought about my options a little more thoroughly, I realized that I could use drop down lists for the user to enter their time, and I can convert it to a date type, and in essence with only a little effort. If we add a calendar control to our form (which this example will assume you did already), you can get a specific date and time.

1. Create our drop down lists

Our end result is to have the following:
Select Class Start Time::


To do so, create three ASP drop down lists, the first for your hours, the second for your minutes (I only needed 15 minute intervals), and the third for your "AM" or "PM" selection.

2. Create your function

How does that song go, "conjunction junction, what's your function?" Sorry, got a little off track there ;)

Converting our selections into a specific time, there is some logic to consider. First of all, keep in mind that the default time to a date datatype is 12:00 AM, so that is your time to start with. So, with that in mind, the way you handle a selection of "12:30 AM" is very different than how you would handle "4:15 PM".

I know, I know.. less talky more codey.. ok, here's your function:


Function ConvertToDate(ByVal HrCtrl As System.Web.UI.WebControls.DropDownList, _
ByVal MinCtrl As System.Web.UI.WebControls.DropDownList, _
ByVal AMPMCtrl As System.Web.UI.WebControls.DropDownList, _
ByVal StartDate As Date) As Date

'Set the date of the class, StartDate is passed in from the selected date from our Calendar control, which is NOT depicted in this example!
Dim ourDate As Date = StartDate
'Get the hour selected
Dim Hour As Double = CDbl(HrCtrl.SelectedValue)
'Get the Minutes selected
Dim Min As Double = CDbl(MinCtrl.SelectedValue)
'A boolean value for AM/PM... remember, by default the time is 12:00 AM
Dim PM As Boolean = False
'Is our selected AM/PM value PM?
If AMPMCtrl.SelectedValue = "PM" Then PM = True
'If the selected time was 12:00 AM, we do nothing with the hours
If (Hour = 12 And Not PM) Then
'Just add any minutes.. if any
ourDate = ourDate.AddMinutes(Min)
Else
'Add any hours selected in the hour select box
ourDate = ourDate.AddHours(Hour)
'Now add any minutes
ourDate = ourDate.AddMinutes(Min)
'If the selected AM/PM is PM, we MAY have to add 12 hours to the current time
If PM Then
'If the selected hour is NOT 12, then we add 12 hours, otherwise adding 12 hours to
'the additional 12 hours would cause the time to be incorrect

If Hour <> 12 Then
ourDate = ourDate.AddHours(CDbl(12))
End If
End If
End If

Return
ourDate

End Function


As you can see, the function above isn't very complicated. It's parameters are your ASP.NET controls you created in step 1, so it's a little more sophisticated and flexible than just accepting plain text values.

It starts out by converting your hours and minuted to double precision values. The reason for this is because the AddHours and AddMinutes functions both accept a double datatype. Next, we check to see if both the hour "12" and "AM" was selected. If so, all we want to do is add any minutes selected, since adding 12 hours to the default time of 12 AM would make the time 12 PM, which is obviously incorrect. If 12:xx AM wasn't selected, we add any hours and minutes to our time. Finally, we check if "PM" was selected. If it was, and "12" wasn't selected, we add 12 additional hours to our time, making it a "PM" time.

3. Call our function

The hardest part is done, all we have to do now is call our function above. You can do so by using code similar to the following.

Dim ourSelectedDate As Date = ConvertToDate(Me.OurHourControl, Me.OurMinuteControl, _
Me.OurAMPMControl, Me.OurCalendarControl.SelectedDate)

As stated throughout this example, we assume that you have a Calendar control on your page, and we pass the date as our last parameter. If you don't need a Calendar control, then just pass a date in for that parameter instead. With this function created, if you have a need to create a date/time range from select boxes, you can use one function for all of your needs. And, it's fairly efficient to boot!

Besides that, that's all you need to return a date/time from a series of drop down lists. Pretty simple, eh???

Labels: , , , ,