ASP.NET Application Deployment Best Practices – Part 1

Over the last few months I have been collecting best practices for deploying ASP.NET applications to production.  The intent was to create a document that described the necessary steps needed to deploy consistent, reliable, secure applications that are easily maintainable for administrators.  The result was an 11 page document.  I would like to take a couple excerpts from it and essentially list what I believe to be key requirements for production applications.

The key is consistency.

  • Generate new encryption keys

The benefit to doing this is that internal hashing and encrypting schemes use different keys between applications. If an application is compromised, the private keys that can get recovered will have no effect on other applications. This is most important in applications that use Forms Authentication such as the member’s section. This Key Generator app is using built-in .NET key generation code in the RNGCryptoServiceProvider.

  • Version and give Assemblies Strong Names

Use AssemblyInfo.cs file:

[assembly: AssemblyTitle("NameSpace.Based.AssemblyTitle")]
[assembly: AssemblyDescription("This is My Awesome Assembly…")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("My Awesome Company")]
[assembly: AssemblyProduct("ApplicationName")]
[assembly: AssemblyCopyright("Copyright © 2009")]
[assembly: AssemblyTrademark("TM Application Name")]
[assembly: AssemblyCulture("en-CA")]

Strong names and versioning is the backbone of .NET assemblies. It helps distinguish between different versions of assemblies, and provides copyright attributes to code we have written internally. This is especially helpful if we decide to sell any of our applications.

  • Deploy Shared Assemblies to the GAC
    • Assemblies such as common controls
    • gacutil.exe -I "g:\dev\published\myApp\bin\myAssembly.dll"

If any assemblies are created that get used across multiple applications they should be deployed to the GAC (Global Assembly Cache). Examples of this could be Data Access Layers, or common controls such as the Telerik controls. The benefit to doing this is that we will not have multiple copies of the same DLL in different applications. A requirement of doing this is that the assembly must be signed and use a multipart name.

  • Pre-Compile Site: [In Visual Studio] Build > Publish Web Site

Any application that is in production should be running in a compiled state. What this means is that any application should not have any code-behind files or App_Code class files on the servers. This will limit damage if our servers are compromised, as the attacker will not be able to modify the source.

  • Encrypt SQL Connections and Connection Strings

Encrypt SQL Connection Strings

Aspnet_regiis.exe -pe connectionStrings -site myWebSite -app /myWebApp

Encrypt SQL Connections

Add ‘Encrypt=True’ to all connection strings before encrypting

SQL Connections contain sensitive data such as username/password combinations for access to database servers. These connection strings are stored in web.config files which are stored in plain-text on the server. If malicious users access these files they will have credentials to access the servers. Encrypting the strings will prevent the ability to read the config section.

However, encrypting the connection string is only half of the issue. SQL transactions are transmitted across the network in plain-text. Sensitive data could be acquired if a network sniffer was running on a compromised web server. SQL Connections should also be encrypted using SSL Certificates.

  • Use key file generated by Strong Name Tool:

C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\sn.exe

“sn.exe -k g:\dev\path\to\app\myAppKey.snk”

Signing an assembly provides validation that the code is ours. It will also allow for GAC deployment by giving the assembly a signature. The key file should be unique to each application, and should be kept in a secure location.

  • Set retail=”true” in machine.config

<configuration>

<system.web>

<deployment retail="true"/>

</system.web>

</configuration>

In a production environment applications do not want to show exception errors or trace messages. Setting the retail property to true is simple way to turn off debugging, tracing, and force the application to use friendly error pages.

In part 2 I continue my post on more best practices for deployment to a production environment.

Single Sign-On

Is it just me, or is Microsoft the only vendor out there that gives you SSO in all their products, free?  Novell requires you buy their add-on product.  Oracle has nothing relevant.  Never gonna happen on any Linux distro out of the box.  Too many variables.

The integration alone is reason enough to use Microsoft products.  Is it just me, or do people choose to go anti-Microsoft out of spite?

Just a thought.

Resources from the SQL 2008 Spatial Data Presentation

sql2008Geo

Here is the presentation.  Click the screen shot to download a ZIP of the demo and slide deck.

Presentation on Geospatial Data(types) in SQL 2008 &amp;ndash; June 4th

I will be giving a presentation on Geospatial data in SQL 2008 for the Toronto SQL User Group on June 4th.  It’s a full session of everything geodetic.  There is no registration, so just show up.  Doors open around 6:15 PM.  The address is: Nexient 2 Bloor St. West at Yonge, downtown Toronto – 12th floor, Room 5.

Map picture

This is interesting&amp;hellip;

image

I’m fairly certain there’s a good reason for this, but I just thought it was interesting because these are not hashes.  They are actual encrypted passwords.  Statistically improbable to get something like this in production systems.  Completely understandable in development.  Just thought it was interesting to see.

Random Insert/Select with T-SQL

Here’s something I found pretty useful. The situation is I need to insert entries into the database with one of the columns being some random data. If I did a Rand() directly in the statement:

Insert into NewStudy
select studyid,((29 + 1) - 27) * Rand() + 27,null from StudyTable

It will only generate Rand() once and fill in all rows with the same data, which is not what I want.

In order to generate a random number for each row, I have to create a view of the RAND() function:

CREATE VIEW vRandNumber
AS
SELECT RAND() as RandNumber
go
 
Insert into NewStudy
select studyid,((29 + 1) - 27) * (select RandNumber from vRandNumber) + 27,null 
from StudyTable

This works very well. Of course, 29 and 27 are my min and max respectively. I can create a separate function to do the same thing:

CREATE FUNCTION RandNumber(@Min int, @Max int)
RETURNS float
AS
 BEGIN
 RETURN @Min + (select RandNumber from vRandNumber) * ((@Max+1)-@Min)
 END

So instead, I can do RandNumber(27, 29) within the statement.

The problem why I didn’t use this randomization is because of permissions. Elevating a standard user to allow creation of a view is disallowed in my situation.

So this is what I did instead, to keep within the boundaries of the permissions, is to use row_number() instead. Take the mod of row_number by ((@Max + 1) - @Min) which is 3 for my case and add the @Min to it. It’s not random, but deterministic, but it works well enough for my case.

Insert into NewStudy
select studyid, (row_number() over (order by studyid)) % 3 + 27,null
from StudyTable

So that’s it. A deterministic pseudo “random” (not so random it seems) number based on row_number(). I wonder if there are other solutions to this.

Windows LiveID Almost OpenID

liveopenidThe Windows Live team announced a few months ago that their Live ID service will be a new provider for the OpenID system.  The Live team was quoted:

Beginning today, Windows Live™ ID is publicly committing to support the OpenID digital identity framework with the announcement of the public availability of a Community Technology Preview (CTP) of the Windows Live ID OpenID Provider.

You will soon be able to use your Windows Live ID account to sign in to any OpenID Web site.

I saw the potential in OpenID a while ago, long before I heard about Microsoft’s intentions.  The only problem was that I didn’t really find a good way to implement such a system on my website.  Not only that, I didn’t really have a purpose for doing such a thing.  The only reason anyone would need to log into the site would be to administer it.  And seeing as I’m the only person who could log in, there was never a need.

Then a brilliant idea hit me.  Let users create accounts to make comment posting easier.  Originally, a user would leave a comment, and I would log in to verify comments, at which point the comment would actually show up.  Sometimes I wouldn’t log in for a couple days, which meant no comments.  So now, if a user wants to post a comment, all they have to do is log in with their openID, and the comment will appear.

Implementing OpenID

I used the ExtremeSwank OpenID Consumer for ASP.NET 2.0.  The beauty of this framework is that all I have to do is drop a control on a webform and OpenID functionality is there.  The control handles all the communications, and when the authenticating site returns it’s data, you access the data through the control’s properties.  To handle the authentication on my end, I tied the values returned from the control into my already in place Forms Authentication mechanism:

if (!(OpenIDControl1.UserObject
== null)) { if (Membership.GetUser(OpenIDControl1.UserObject.Identity)
== null) { string email = OpenIDControl1.UserObject
.GetValue(SimpleRegistrationFields.Email); string username = ""; if (HttpContext.Current.User.Identity != null) { username = HttpContext.Current.User.Identity.Name; } else { username = OpenIDControl1.UserObject.Identity; } MembershipCreateStatus membershipStatus; MembershipUser user = Membership.CreateUser( username, RandomString(12, false), email, "This is an OpenID Account. You should log in with your OpenID", RandomString(12, false), true, out membershipStatus ); if (membershipStatus != MembershipCreateStatus.Success) { lblError.Text
= "Cannot create account for OpenID Account: "
+ membershipStatus.ToString(); } } }
That’s all there is to it.

What Makes us Want to Program? Part 4

In my previous post, I started talking about using Microsoft technologies over PHP and open source technologies.  There were a couple reasons why I chose to make the move.  First, from a development perspective, everything was object oriented.  PHP was just getting started with OOP at the time, and it wasn’t all that friendly.  Second, development time was generally cut in at least half, because of the built in controls of ASP.NET.  Third, the end result was a more rich application experience for the same reason.  The final reason comes down to the data aspect.

Pulling data from a database in PHP wasn’t easy to do.  The built in support was for MySQL, with very little, if next to nothing for SQL Server.  In a lot of cases that isn’t always a bad thing.  MySQL is free.  You can’t argue with that.  however, MySQL wasn’t what you would call ACID compliant.  Defined, MySQL did not have the characteristics of being Atomic, Consistent, Isolated, and Durable.  Essentially, when data goes missing, there is nothing you can do about it.  SQL Server on the other hand is very ACID compliant.  This is something you want.  Period.

Once .NET 2.0 was released, a whole new paradigm came into play for data in a web application.  It was easy to access!  No more, or at least next to very little boiler plate coding was necessary for data access now.  Talk about a selling point.  Especially when the developer in question is 16 going on 17.

Now that I didn’t need to worry about data access code, I could start working on figuring out SQL.  At the time t-SQL scared the crap out of me.  My brain just couldn’t work around datasets.  The idea of working with multiple pieces of data at once was foreign.  I understood single valued iterations.  A for loop made sense to me.  SELECTs and JOINs confused me.  Mind you, I didn’t start Statistics in math until the following year.  Did SQL help with statistics, or did statistics help me finally figure out SQL?  It’s a chicken and the egg paradox.

So here I am, 17 years old, understanding multiple languages, building dozens of applications, and attending developer conferences all the while managing my education in High School.  Sweet.  I have 3 years until the next release of Visual Studio comes out.  It was here that I figured I should probably start paying more attention in school.  It’s not so much that I wasn’t paying attention, it’s just that I didn’t care enough.  I put in just enough effort to skate through classes with a passing mark.  It was also at this point in time that I made an interesting supposition.

Experts tend to agree that people who are programming geniuses are also good at math and critical thinking or reasoning.  Not one or the other, but both.  Now I’m not saying I’m a programming genius, but I suck at math.  It was just never in the cards.  But, according to all those High School exams and the psychological profiling they gather from them, my Critical Thinking and Reasoning skills are excellent.  Top 10% in Canada according to the exam results.  My math skills sit around top 20-30% depending on the type.

Neurologists place this type of thinking in the left hemisphere of the brain.  The left brain is associated with verbal, logical, and analytical thinking. It excels in naming and categorizing things, symbolic abstraction, speech, reading, writing, arithmetic.  Those who live in the left brain are very linear.  Perfect for a software developer.

The supposition I made had more to do with the Pre-Frontal Cortex of the brain.  It does a lot of work, some of which is planning complex cognitive behaviors.  Behaviors like making a list, calculating numbers, abstracting thoughts, etc.  It plans out the processes our brains use to get things done.  This is true for both sides of the brain.  So, suppose you are left brain-oriented.  You are predisposed to be good at development.  Now, suppose your Pre-Frontal Cortex is very well developed, more so than the average person.  It could be reasoned that part of being a programming genius is having a well developed Pre-Frontal Cortex.

So why does this make us want to program?  Find out in Part 5.

What Makes us Want to Program? Part 3

In my second post I discussed my run in with ASP, and how PHP was far better.  I ended the post talking about an invitation to a Microsoft event.  This was an interesting event.  Greg and I were the only people under 30 there.  When that’s a 15 year difference, things get interesting.  Especially when you need your mother to drive you there…  The talk was a comparison between Microsoft based technologies and Linux based technologies.  The presenter was a 10 year veteran of IBM, working on their Linux platform, who then moved to Microsoft.  For the life of me I can’t remember his name.

His goal was simple.  Disprove myths around Linux costs versus Windows costs.  It was a very compelling argument.  The event was based around the Windows Compare campaign.  It was around this time that Longhorn (Longhorn that turned into Vista, not Server 2008) was in pre-beta soon to go beta, and after discussing it with Greg, we decided to probe the presenter for information about Longhorn.  In a situation like that, the presenter either gets mad, or becomes really enthusiastic about the question.  He certainly didn’t get mad.

Throughout the rest of the talk, the presenter made some jokes at mine and Greg’s expense, which was all in good fun.  Based on that, we decided to go one step further to ask how we can get the latest Longhorn build, at one of the breaks.  the conversation went something like this:

Me: So how do people get copies of the latest build for Longhorn?
Presenter: Currently those enrolled in the MSDN Licensing program can get the builds.
Me: Ok, how does one join such a licensing program?
Presenter: Generally you buy them.
Me: How much?
Presenter: A couple thousand…
Me: Ok let me rephrase the question.  How does a student, such as myself and my friend Greg here, get a the latest build of Longhorn when we don’t have an MSDN subscription, nor the money to buy said subscription?
Presenter: *Laughs* Oh.  Go talk to Alec over there and tell him I said to give you a student subscription.
Me:  Really?  Cool!

Six months later Greg and I some how got MSDN Premium Subscriptions.  We had legal copies of almost every single piece of Microsoft software ever commercially produced.  Visual Studio 2005 was still in beta, so I decided to try it out.  I was less than impressed with Visual Studio 2003, but really liked ASP.NET, so I wanted to see what 2005 had in store.  At the time PHP was still my main language, but after the beta of 2005, I immediately switched to C#.  I had known about C# for a while, and understood the language fairly well.  It was .NET 1.1 that never took for me.  That, and I didn’t have a legal copy of Visual Studio 2003 at the time.

Running a Longhorn beta build, with Visual Studio 2005 beta installed, I started playing with ASP.NET 2.0, and built some pretty interesting sites.  The first was a Wiki type site, designed for medical knowledge (hey, it takes a lot to kill a passion of mine).  It never saw the light of day on the interweb, but it certainly was a cool site.  Following that were a bunch of test sites that I used to experiment with the data controls.

It wasn’t until the release of SQL Server 2005 that I started getting interested in data.  Which I will discuss in the my next post.

What Makes us Want to Program? Part 2

In my previous post I started talking about part of my personal history with software development, and when QBasic got me hooked.  I ended the post talking about the move to Canada.  We arrived in Canada literally a week (7 days exactly) before Grade 9 started.  After getting enrolled in school, I tried to find something to keep my mind occupied.  It was either that or contemplate what Grade 9 would be like for someone who used to live 3000 miles away in another country.  And winter.  Still 4 months away, but definitely something I didn’t want to think about.  Being that we moved to a house in the country, I couldn’t just walk around town either.  Mental occupation was harder than I thought.

So what does a 14 year old boy, new to the country, living in the middle of nowhere, do to keep himself from going crazy?  Install Linux of course!  I needed something to keep my interest, as well as to keep the gears in my head moving.  If memory serves, I started out with a vanilla copy of Red Hat Linux.  It was pretty easy to install, but being new to the OS architecture, the device mapping was a little confusing.  After a couple months of studying the Linux architecture, I started writing shell scripts, and even delved into the source code.  After testing some minor modifications to different components I started to learn the basis for the C/C++ languages.  Imagine that, a 14 year old kid understanding the basis for C++.

While trying to keep my mind still occupied, I came across an interesting find: The National Security Agency’s Security Enhanced Linux Kernel.  If compiled and installed wrong, you will destroy the build.  Learned that the hard way…  And seeing as I couldn’t find a proper driver for my modem anyway, I gave up on Linux and moved back to XP.  Not that the internet was all that useful anyway; I was connecting at 28.8 half the time.

Going back to the image in Part 1, I met an interesting character in school.  He turned out to be one of my best friends, and fellow developers, Greg. We started working on some odd projects here and there in VB, until I was tasked with building a web store.  Since I had never actually brought HTML and Dev together, I was a little nervous about what I was getting myself into.  Going with what I knew well, I started in ASP with VB code.  This was not ASP.NET.  Earlier, I had said I never found VB all that intuitive as a language.  The syntax never really made sense to me.  So my friend suggested I take a look at PHP as an alternative.  I liked it.

PHP had the flow of C, and the usefulness of VB.  With PHP I got the store finished and launched.  The site worked great.  I was 15.

Once the first spring of my existence in Canada rolled around, a couple friends and I decided to start a band.  We sucked.  But seeing as one of the other members was Greg, we had an awesome website.  We had media streaming, custom modified forums, and full site statistics.  The statistics were built around the forum.  The site pulled data from recent posts, recent events, and recent user logins, and compared the data to the media streams.  We could see who was doing what.  Mind you, there was only about 50 people who loitered around the site, but the site was a great proof of concept for what we could do.

Following the demise of the band, Greg and I were invited to a Microsoft hosted event.  It was here that I fell in love with ASP.NET.  Which I will discuss in Part 3.