Sections
spotlight
     
     
WWWCoder.com Resource Directory

Creating a Single Sign-on for ASP.NET Application and Legacy ASP Application (Part II)
4/26/2005 10:49:36 AM

A hack into the .NET authentication classes to extract a component that can be called by legacy asp applications to generate the same authentication token used in asp.net applications.

Ting Huang

A hack into the .NET authentication classes to extract a component that can be called by legacy asp applications to generate the same authentication token used in asp.net applications.

(Link to part I: http://www.wwwcoder.com/main/parentid/258/site/2598/68/default.aspx)

Introduction

In part I of the article, I introduced a way to create a single sign-on between asp and asp.net applications. Although the solution is sound, it is not without shortcomings:

1. While the authentication token generated is different each time, it is not time-stamped. Hence, there is no expiration by itself. This could lead to a high risk of being maliciously reused when the token is hijacked.

2. It is not a time-saving or effort-saving solution, because additional development is required on both sides of asp and asp.net applications to manage the authentication token.

It would be ideal if the forms authentication mechanism from ASP.NET can be utilized by ASP application to generate or verify authentication token efficiently. Additionally, the token generated should be automatically recognized as a valid token by ASP.NET built-in forms authentication mechanism as well.

Inspired by a Microsoft knowledge-base article at http://support.microsoft.com/default.aspx?scid=kb;EN-US;891028 which makes a web service to provide authentication methods for ASP application, I got the idea of using the asp.net FormsAuthentication utilities directly in classic asp. To circumvent the initialization problem, I extracted the core functionalities apart from the FormsAuthentication utilities and removed the requirements for HttpContext and other related classes that are only available in asp.net. The asp scripts will be able to use simple COM interop to call into this authentication component to retrieve as well as verify tokens.

How Forms Authentication Works in ASP.NET

What happens behind the scene of the form authentication mechanism in ASP.NET is that when a client request goes through the http pipeline, the FormsAuthenticationModule (a HttpModule) picks up the incoming request and tries to extract authentication ticket from cookie. The process requires decryption and reading configurations via HttpContext.

Solution

The solution is to extract the core functionalities apart from the FormsAuthentication utilities in ASP.NET and remove the requirements for HttpContext and other related classes and make them into a authentication component that can be called by ASP application.

Here is how the solution looks like:

The following steps show how to get the solution working.

1. Synchronize the encryption and decryption key

Forms authentication in asp.net uses the <machineKey> element in machine.config or web.config for encryption and decryption authentication token:

<machineKey validationKey="AutoGenerate|value[,IsolateApps]" decryptionKey="AutoGenerate|value[,IsolateApps] validation="SHA1|MD5|3DES"/>

If you have run ASP.NET applications in a server farm, you probably know that the machine key has to be set with the same value on all severs in the farm. This ensures that tokens generated on one of the servers can be validated on another. For the same reason, it is necessary to synchronize the encryption and decryption key in both ASP.NET forms authentication and the custom authentication component.

The following link can be used to generate a machine key setting:

http://www.eggheadcafe.com/articles/GenerateMachineKey/GenerateMachineKey.aspx

The following is an example of such setting:

<machineKey validationKey='6C0D4C65DBD3CF60C037E0BE43D2958954DA9AAA830D902B8481DDDF962A
4E392056DE5EEEEC0061673BB413DB533D6F8C61C70AD36C9F89F99DC0B3AD292B53'  
decryptionKey='7EBC8C30854618249344BAF797E1B9DD119F249D459C006D'   validation='SHA1'/>

This is the only change has to be made in ASP.NET for the single sign-on to work.

2. Create a COM wrapper for authentication

This is the ‘bare bone’ class for the authentication API.

public class AuthAPI
{
public AuthAPI()
      {} 

      public void Initialize()
      {
            FormsAuthentication.Initialize();
      }
       public void Initialize1(
            string cookieName,
            string cookieDomain,
            string cookiePath,
            bool slidingExpiration,
            int timeout,
            bool requireSSL
            )
      {
            FormsAuthentication.Initialize(
                  cookieName,
                  cookieDomain,
                  cookiePath,
                  slidingExpiration,
                  timeout,
                  requireSSL
                  );
      } 

      public void Initialize2(
            string cookieName,
            string cookieDomain,
            string cookiePath,
            bool slidingExpiration,
            string protection,
            int timeout,
            bool requireSSL,
            string validationKey,
            string decryptionKey,
            string validationMode
            )
      {
            FormsAuthentication.Initialize(
                  cookieName,
                  cookieDomain,
                  cookiePath,
                  slidingExpiration,
                  (FormsProtectionEnum)Enum.Parse(typeof(FormsProtectionEnum), protection, true),
                  timeout,
                  requireSSL,
                  validationKey,
                  decryptionKey,
                  (FormsCryptoValidationMode)Enum.Parse(typeof(FormsCryptoValidationMode), validationMode, true)
                  );
      }

      public string GetAuthCookieValue(
            string
userName,
            bool
createPersistentCookie)
      {
            HttpCookie cookie = FormsAuthentication.GetAuthCookie(userName, createPersistentCookie);
            return cookie.Value;
      }

       public bool IsAuthenticated(
            string
cookieValue,
            out
string newCookieValue,
            out
DateTime expiration)
      {
            return FormsAuthentication.IsAuthenticated(cookieValue, out newCookieValue, out expiration);
      }
}

Initialize2 method requires validationKey, decryptionKey and validationMode as well as other parameters being passed in order for the custom FormsAuthentication to be initialized. The two other initialization methods will use the default keys in the class. To make the COM call easier, don’t use overloads in C# for the initialization methods.

GetAuthCookieValue method works almost the same as GetAuthCookie in ASP.NET FormsAuthentication class except that it doesn’t return a HttpCookie object but rather a string value of the cookie to be written directly to client’s browser.

IsAuthenticated method validates the incoming cookie if it is a valid authentication cookie. If a renew action is required for the cookie on the caller, it will return value in the newCookieValue parameter, otherwise, it will be empty. The expiration DateTime value gives convenience to the caller when it performs the renew action.

3. Making a new asp authentication script

To retrieve the authentication cookie:

<%          cookieName               =          ".ASPXAUTH"
            cookieDomain             =          "yourdomain"
            cookiePath               =          "/"

            Set ulogin = Server.CreateObject("SingleSignon.AuthAPI")
            uLogin.Initialize1 cookieName, cookieDomain, cookiePath, 1, 20, 0
            s = uLogin.GetAuthCookieValue(cookieName, false)
            Call AddCookie ( cookieName, s )
            set ulogin = nothing
%>

<%      Set ulogin = Server.CreateObject("SingleSignon.AuthAPI")
            isLogin =  uLogin.IsAuthenticated(GetCookie(uLogin.FormsCookieName, ""), newCookieValue, expiration)
            If not isLogin then
                        ‘ user is not logged in, redirect to login page
            Else
                        ‘ user is logged in
                        If not isempty(newCookieValue) then
                        'renew cookie
                                Call AddCookie ( cookieName, newCookieValue, expiration )
                        End If
            End If
            Set ulogin = nothing
%>

Conclusion

In this article, a custom authentication component is extracted from the ASP.NET forms authentication utilities to remove any HttpContext initialization so that it can be called directly in classic ASP scripts through COM interface. The authentication token obtained via this API component works between ASP.NET and ASP application, with minimum setting in ASP.NET’s forms authentication. It also works efficiently without a web service workaround.

There are more that can be done based on this solution. These include:

  1. Update the Authentication API to read configurations from ASP.NET application. This can either be done via web service or direct access to the config file in ASP.NET. The advantage is to avoid explicitly passing encryption keys;
  2. Use Session or any other available solutions to maintain the state, so that calling the Authentication API for every authentication request in ASP can be avoided.

References

For more information, please see the following resources:
ASP.NET security overview (http://support.microsoft.com/default.aspx?scid=kb;EN-US;891028 )

Download the code!


Page Options:
format for printing  Format for Printer
email article  Email Page
add to your favorites   Add to Favorites
How would you rate the quality of this content?
Poor - - Excellent
Comments?
Overall Rating:
Comments Left:
Left on 4/24/2009 5:04:35 AM by Anonymous
Comments:
Left on 2/10/2009 11:44:53 AM by Anonymous
Comments: code can be found here:
http://www.wwwcoder.com/portals/1/SSOII42605.rar
No ratings available.
Left on 11/6/2008 4:43:12 AM by Anonymous
Comments: cannot download code
No ratings available.
Left on 5/21/2007 5:17:15 AM by Anonymous
Comments: eee
Left on 1/6/2007 6:47:23 PM by Anonymous
Comments: I met with the same error, is there any resolution?
No ratings available.
Left on 1/22/2006 8:56:17 PM by Anonymous
Comments: is it the cause that the version singlesignon compile with discrepant to version that singlesignon register with 
No ratings available.
Left on 1/22/2006 2:37:26 AM by Anonymous
Comments: v strangely sometime I got the unable to load dll(aspnet_isapi.dll) error and ran register.bat doesn't work.
No ratings available.
Left on 8/31/2005 3:42:30 AM by Anonymous
Comments: Run register.bat in the download file. --Ting H
No ratings available.
Left on 8/5/2005 11:34:02 AM by Anonymous
Comments: I am also getting the Unable to load DLL (aspnet_isapi.dll) error. Has anyone gotten past this ?

No ratings available.
Left on 6/21/2005 3:14:17 PM by Anonymous
Comments: I'm getting errors on the login.asp page even after running the register.bat file.  "Error Type:
SingleSignon (0x80131524)
Unable to load DLL (aspnet_isapi.dll).
/WebSSO/Login.asp, line 9"  Any suggestions?
No ratings available.
     
     

 

     
     

 


 


Digg This
 


DotNetNuke Platinum Benefactor

     
     

Other family network sites: santry.com - katieandkarleigh.com

Powered by 

 

     
Copyright 20010 - Santry Technology Solutions, Box 172, Girard, PA 16417, (814) 774-0970
Privacy Statement | Terms Of Use