ASP.NET (and Silverlight) authentication woes

For one of my Silverlight projects, I need to allow my users to create account on my database. It’s not at all obvious how to go about this, but I was able to solve it after tons of  googling.

[For a simpler method, see this blog post a minimal silverlight authentication implementation]

If you start out with a standard Visual Studio installation, a SQL Server Express installation is included – and that database will automatically be used for authentication. I didn’t include SQL Server Express with my installation, so I’ve had to add the authentication tables afterwards. And that actually suits me just fine, because I really want my authentication tables to be stored with the rest of my application data, in a database that’s been custom designed for this project.

If you create a Silverlight application based on the Silverlight Buisness Application template, you’ll be using the ASP.NET authentication system. Unless you override it with your own MembershipProvider, but I’ll save that for a later blog…

The tables you’ll need

Looking at a database that’s prepared for handing ASP.NET authentication, the following tables must exist on your database;

aspnet_Applications
aspnet_Membership
aspnet_Paths
aspnet_PersonalizationAllUsers
aspnet_PersonalizationPerUser
aspnet_Profile
aspnet_Roles
aspnet_SchemaVersions
aspnet_Users
aspnet_UsersInRoles
aspnet_WebEvent_Events

They’re all all be placed in the dbo namespace. On top of these tables, you’ll also find these views;

vw_aspnet_Applications
vw_aspnet_MembershipUsers
vw_aspnet_Profiles
vw_aspnet_Roles
vw_aspnet_Users
vw_aspnet_UsersInRoles
vw_aspnet_WebPartState_Paths
vw_aspnet_WebPartState_Shared
vw_aspnet_WebPartState_User

And loads and loads of stored procedures.

Adding asp.net tables to an existing database

If you, like me, have an existing database to which you’d like to add these tables, you must use the tool ASP.NET SQL Server Registration Tool (Aspnet_regsql.exe). According to the documentation, it should be found in “[drive:]\%windir%\Microsoft.NET\Framework\version” on your webserver/development machine, but I found that I only have it in the v2.0.50727 folder, not the v3.0 or v3.4 folders.

It’s fairly straight forward to use, just start it and you’ll be greeted with a wizard to walk you through the process.

Silverlight Business Application login fails

“Load operation failed for query ‘Login’. Could not connect to SQL Server.”

If you’ve followed my instructions this far, you’ll get the above error message whenever you try to login. Why? Well, so far, the application doesn’t know where to find the tables.

By default, the .NET framework will try to use the AspNetSqlMembershipProvider and it will try to find the required tables on a server specified by the connection-string “LocalSqlServer”.

Connecting your application to your new authentications

Create a connection string in your Web.config file that points to the database that contains your login information;

  <connectionStrings>
    <remove name="LocalSqlServer"/>
    <add
      name="LocalSqlServer"
      connectionString="Data Source=localhost;Initial Catalog=ImageEvolvatron;Integrated Security=True"
      providerName="System.Data.SqlClient"/>
  </connectionStrings>

Now update your membership provider to use the connectionstring in question;

    <membership>
      <providers>
        <remove name="AspNetSqlMembershipProvider"/>
        <add name="AspNetSqlMembershipProvider"
          type="System.Web.Security.SqlMembershipProvider,
            System.Web, Version=2.0.0.0, Culture=neutral,
            PublicKeyToken=b03f5f7f11d50a3a"
          connectionStringName="LocalSqlServer"
          enablePasswordRetrieval="false"
          enablePasswordReset="true"
          applicationName="/"
          requiresUniqueEmail="false"
          passwordFormat="Hashed"
          maxInvalidPasswordAttempts="5"
          minRequiredPasswordLength="7"
          minRequiredNonalphanumericCharacters="1"
          passwordAttemptWindow="10"
          passwordStrengthRegularExpression=""
          requiresQuestionAndAnswer="false"/>
      </providers>
    </membership>

Still can’t login…

LoginFailed

But that’s to be expected – at least the error message indicates that we’re oh, so close now. We’ll need to create the account first, hit “Register now” and fill out the form. And voila, we have login success;

LoginSuccess

But I want my own tables!

[For a simpler method, see this blog post a minimal silverlight authentication implementation]

If you’re like me, you don’t want to store your information in these tables, you’ll want to design your own tables. To do this, you’ll have to implement a number of your own support classes.

For my Silverlight project, I tried to only implement the MembershipProvider, but I failed because it seems I also need a role provider and a ProfileProvider.

The code below is cut from the Web application that was generated with my Silverlight Business Application;

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void AddUser(RegistrationData user)
        {
            // RoleProvider is used in the background
            if (!Roles.RoleExists(UserRegistrationService.DefaultRole))
            {
                Roles.CreateRole(UserRegistrationService.DefaultRole);
            }

            // MembershipProvider is used in the background
            MembershipCreateStatus createStatus;
            Membership.CreateUser(user.UserName, user.Password, user.Email, user.Question, user.Answer, true, null, out createStatus);

            if (createStatus != MembershipCreateStatus.Success)
            {
                throw new DomainException(ErrorCodeToString(createStatus));
            }

            // RoleProvider is used in the background
            Roles.AddUserToRole(user.UserName, UserRegistrationService.DefaultRole);

            // Profile provider is used in the background
            ProfileBase profile = ProfileBase.Create(user.UserName, true);
            profile.SetPropertyValue("FriendlyName", user.FriendlyName);
            profile.Save();
        }

MembershipProvider

You’ll need your own MembershipProvider, how to implement your own is explained in multiple examples online, for instance here and here. The MembershipProvider is responsible for storing your accounts, retrieving the accounts and authenticating the accounts.

RoleProvider

You’ll need your own RoleProvider, how to implement your own is explained in multiple examples online, for instance here and here. The RoleProvider is responsible for storing retrieving roles and connecting users to Roles. If you don’t intend to use roles, you can probably do without it – but my attempts to skip it has so far failed…

ProfileProvider

You’ll need your own ProfileProvider. The ProfileProvider is responsible for storing additional information about your users, information that’s not handled by the MembershipProvider. If you don’t intend to store additional information, or you intend to store it in somekine of separate storage, you can probably do without it. But again, my attemps to skip it has so far failed…

About mfagerlund
Writes code in my sleep - and sometimes it even compiles!

5 Responses to ASP.NET (and Silverlight) authentication woes

  1. Pingback: (Silverlight) Switching between LINQtoSQL and Entity Framework « Mattias Fagerlund's Coding Blog

  2. Pingback: Silverlight, Minimal Authentication Implementation « Mattias Fagerlund's Coding Blog

  3. Pingback: 2010 in review « Mattias Fagerlund's Coding Blog

  4. mike okon says:

    Hi
    Nice post, Im in the same boat as you, however I just need to tweek the registration part. You see I dont need the security question. How can I remove it from the register window? Also I have my own tables for users which holds user data. In fact I have another table which holds a list of valid users. How can I validate a username against my own table when a user tries to register. So as to limit who is able to register. (by username)

    thanks in advance
    mike okon

  5. mfagerlund says:

    Did you check out the next blog post https://lotsacode.wordpress.com/2010/03/19/silverlight-minimal-authentication-implementation/ – that uses custom storage and should be closer to what you need.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: