June 20, 2018
Hot Topics:

Asynchronous, High-Performance Login for Web Farms

  • December 26, 2007
  • By Udi Dahan
  • Send Email »
  • More Articles »

And the code that the web server runs on startup looks like this (assuming constructor injection):

public class UserAuthenticationServiceAgent
   public UserAuthenticationServiceAgent(IBus bus)
      this.bus = bus;
      // subscribe for updates
      // request the full list
      bus.Send(new GetAllUsernamesMessages());


When the Authentication Service receives the GetAllUsernamesMessage, its message handler accesses its cache of usernames and hashed passwords, and builds a message that is returned to the caller as follows:

public class GetAllUsernamesMessageHandler :
   public override void Handle(GetAllUsernamesMessage message)

And the class on the web server that handles a UsernameInUseMessage when it arrives:

public class UsernameInUseMessageHandler :
   public override void Handle(UsernameInUseMessage message)
      WebCache.SaveOrUpdate(message.Username, message.HashedPassword);

When the app server sends the full list, multiple objects of the type UsernameInUseMessage are sent in one physical message to that web server. However, the bus object that runs on the web server dispatches each of these logical messages one at a time to the message handler above.

So, when it comes time to actually authenticate a user, this the web page (or controller, if you're doing MVC) would call:

public class UserAuthenticationServiceAgent
   public bool Authenticate(string username, string password)
      byte[] existingHashedPassword = WebCache[username];
      if (existingHashedPassword != null)
         return existingHashedPassword == this.Hash(password);

      return false;

When registering a new user, the web server would of course first check its cache, and then send a RegisterUserMessage that contained the username and the hashed password.

public class RegisterUserMessage : IMessage
   private string username;
   public string Username
      get { return username; }
      set { username = value; }

   private string email;
   public string Email
      get { return email; }
      set { email = value; }

   private byte[] hashedPassword;
   public byte[] HashedPassword
      get { return hashedPassword; }
      set { hashedPassword = value; }

When the RegisterUserMessage arrives at the app server, a new long-running workflow is kicked off to handle the process:

public class RegisterUserWorkflow :
   public void Handle(RegisterUserMessage message)
      //send validation request to message.Email containing
      // this.Id (a guid) as a part of the URL

   /// <summary>
   /// When a user clicks the validation link in the email, the
   /// web server sends a UserValidatedMessage containing the
   /// workflow Id
   /// </summary>
   public void Handle(UserValidatedMessage message)
      // write user to the DB

      this.Bus.Publish(new UsernameInUseMessage(
         message.Username, message.HashedPassword));

That UsernameInUseMessage would eventually arrive at all the web servers subscribed.

Page 2 of 3

Comment and Contribute


(Maximum characters: 1200). You have characters left.



Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

By submitting your information, you agree that developer.com may send you developer offers via email, phone and text message, as well as email offers about other products and services that developer believes may be of interest to you. developer will process your information in accordance with the Quinstreet Privacy Policy.


We have made updates to our Privacy Policy to reflect the implementation of the General Data Protection Regulation.
Thanks for your registration, follow us on our social networks to keep up-to-date