HOWTO: Single SignOn (SSO) considerations for ISAPI


A few days ago, I got the following question about single sign on using ISAPI.


Question:


Hi David,


I read some of waht u wrote about ISAPI in http://groups.google.com


I have different servers with different site. Most of them are asp sites and some are asp.net and html (each server has some sites). One of those sites will be the authentication site. If this is valid user (user name /pw or dialing using our phone number) then she/he can view the other sites .How can I handle this problem? How can I share data between those sites? (Like session and cookies with in one site)


I thought ISAPI can handel this am I right?


so this is my first ISAPI(ISAPI for authenticate the user to view a site) and I have some problems with it:(


1-I overrided the funtion OnAuthentication to do the following:


check the username and password form Database(Sql 2000 server) if valid returns SF_STATUS_REQ_HANDLED_NOTIFICATION


else


SF_STATUS_REQ_ERROR


2-I made a new site in the IIS and add the filter to it & made the authentication basic(I guess this is form where the OnAuthentication takes the username and password) am I right?


3-I run REGEDT32.EXE and modify the server’s registry as follows. Select the Filter DLLs key in HKEY_LOCAL_MACHINE\CurrentControlSet\Services\W3SVC\Parameters and add my dll.


Is there somthing missing in those steps in order to make the ISAPI works?


Thx for any help u can offer


Regards,


Answer:


First, you must realize that this is a really loaded question that people usually get paid consulting to handle. Since you are implementing it, I am not going to give any details but instead just point out the general issues that you must handle. You must have a good idea of HTTP (read RFC2616) and the general design of your custom authentication protocol before you think about the technologies necessary to build it. Of course, ISAPI can handle this task, but until you have a good handle on what the tasks are, ISAPI will not be useful.



  1. OnAuthenticate() is only fired when the user attempts Anonymous or Basic authentication, and it allows you to change the username/password that IIS will use to call LogonUser and obtain an NT user token.
  2. If you want IIS to handle the authentication tasks, then you configure IIS to handle non-anonymous authentication. If you want to implement a custom authentication scheme and do NOT want IIS involved in the protocol handshake (it is custom, after all, and IIS does not know anything about it), then make sure to only configure anonymous authentication in IIS
  3. It is incorrect to edit the registry to add ISAPI Filters. It has been deprecated since IIS5, and IIS6 does not even read that registry location. Use the IIS Manager UI to configure the metabase to add the ISAPI Filter, or use a tool like %SYSTEMROOT%\Inetpub\AdminScripts\ADSUTIL.VBS or a custom script if you know what you are doing.

Based on your description, I am certain your filter is not even close to working as you want. You have not solved the following problems:



  1. How does the authentication “state” from one website get transferred to the other websites? HTTP is stateless, so there is no way that logging onto one server automagically allows you to log onto another server. Cookies are also bound per-website, so you cannot get browsers to send the cookies. So, how do sites make Passport work? Once you figure out this solution, ISAPI can help you implement it (early versions of Passport was an ISAPI Filter).
  2. Session is just another form of “state” that needs to transferred, so it is solved analogously as #1. I recommend that you use a shared session server between all the web servers such that users can move between sites without losing session. Once again, realize that ASP has no such notion of a shared session, and ASP.Net has its own implementation of a shared session server, so if you cannot figure out how to make them work for your needs, you may have to build your own (or reformat your problem to be able to use pre-built ones).
  3. How does your ISAPI Filter determine the scope of URLs to protect as well as the means of “authorization”

If this looks daunting, you may want to consider using ASP.Net 2.0 on IIS6 and wildcard scriptmap ASP.Net ISAPI to allow you to write HttpHandlers and HttpModules to do what you want. It will still protect ASP content, and you get to re-leverage a lot of the capabilities in ASP.Net that you have not written yourself. And yes, it is still an ISAPI (the ASP.Net ISAPI) that is doing the real work. It is just a different extensibility interface.


//David

Comments (4)

  1. David.Wang says:

    I got the following comment for this post. Please feel free to reply via comments so that there is a discussion trail that can help others. Direct questions to me for the Blog entry will always become public on the Blog.

    —–>8———->8———->8———->8———->8———->8—–

    Dear Mr. David,

    Thx for your Message (http://blogs.msdn.com/david.wang/archive/2005/04/27/SSO_ISAPI_Considerations.aspx). Hope my question didn’t bug you.

    -In order to simplify the problem I can move all the sites to one IIS (one server). About the authentication it can be either by the ISAPI (basic authentication with SSL or Anonymous) or by a site. Is there a solution for this?

    -What do you mean by "Of course, ISAPI can handle this task, but until you have a good handle on what the tasks are, ISAPI will not be useful.". You recommend going on with ISAPI or not?

    -In first No.1 & No.2, OnAuthenticate() is fired when the user attempts Anonymous authentication = IIS handles the authentication =ISAPI filter and this is differ with No.2? I think there is something I don’t understand?

    -I thought about ISAPI that it can solve the problem because I found a SW doing something like that (after simplifying the problem) using ISAPI. This SW allows u to choose certain folder/folders (say the site/sites u wanna close it with username/password) and give it access to the valid users (username/pw in my data base using ODBC or creating new users using the SW stored in the internal SW data base).when u type the url in the browser, a dialog appears asking for username and pw (like the basic authentication) valid users will view the site else not.

    -What I described about ISAPI code I did was just a first step or a trial to handle the authentication part (like in the SW) but it didn’t work as I told u ?

    Thx for any help u can offer

    Regards,

    —–>8—–

  2. David.Wang says:

    Really, I am not trying to be mean spirited. I am trying to help you in ways that I can.

    What I mean by "Of course, ISAPI can handle this task…" is exactly that. You said yourself that you have found ISAPI SW that does this, but you want to rewrite it yourself for some reason. You have already proven to yourself that ISAPI can handle this task by finding that ISAPI. The issue here is whether *you* know how to program ISAPI to handle this task.

    It should be obvious why I am not going to answer your question about "you recommend going on with ISAPI or not?" You are assuming that technology solve problems when in reality, it is solutions that solve problems. ISAPI is a technology. Solutions are designed by humans and implemented in technology.

    Thus, it is important to first come up with the design for the solution, and then decide on what exact technological steps will implement the solution. You have not yet described a solution (how about starting with the entire authentication protocol sequence – what HTTP data needs to go where, what sequence, and how are you going to persist state that represents "authenticated"), so there is no way for me to answer that a technology is going to allow you to solve your problem.

    Strangely, you seem to be trying to get me to validate that "yes, you are capable enough with ISAPI to implement it using ISAPI" when in reality I do not even know if you have the solution to this problem nor if you can implement it.

    Regarding your other confusion about OnAuthenticate – I am not certain what is confusing. #2 states that if you want to implement a custom authentication scheme and do NOT want IIS involved in the protocol handshake, then make sure to only configure anonymous authentication in IIS. #1 states that anonymous authentication will still trigger the OnAuthenticate() event and allows you to change the username/password that IIS will use to call LogonUser and obtain an NT user token.

    Thus, logic implies that custom authentication can control the user account that IIS uses to process the request. Whether this means anything to you, I do not know. It depends on your solution design, which is still unknown to me.

    I have to repeat this again – until you come up with a solution design, it is premature to select technology to implement the solution.

    Maybe this entire problem space is too complicated for you, and you want to customize on some simpler existing solutions. In that case, I recommend looking at ASP.Net 2.0 on IIS6 which allows managed code extensibility to do this job. But once again, you need to know what your solution is supposed to look like and then map what technology pieces do.

    //David

  3. Josh says:

    I believe that wildard mapping on IIS6 has memory usage implications. Every 5 MB PDF that you pass through the asp.net ISAPI is loaded into memory with each GET request when it’s protected by a HTTP Handler.

  4. David Wang says:

    Josh – Correct, that would be the ASP.Net static file handler and managed code memory "issues" at play. Nothing IIS6 can do about it, but it’s really your easiest option. Pure ISAPI gives you the most control at the cost of development ease.

    //David