SharePoint Basic / Extranet Double Authentication
Age old problem, still existing in SharePoint today, is the dual authentication prompt when you try to open an office document that continually pops up (note: this is when you are working with a document in edit more. In read only it doesn’t require authentication since you aren’t interacting with the document). This happens because of the nature of passing a login token from the riding user session. Meaning, when you open an office application, it is not possible to carry the web session into the client session (and the session holds the relevant user ID), since the session ID is considered new, SharePoint will attempt to verify the user identity again. Ultimately, it would be great if the Windows identity that SharePoint is using could persist across this boundary, however it isn’t in the cards right now. The first mechanism to get around is WSS v3 has an option that is available called “extranet mode”. Extranet mode will disable all those features from the interface that would otherwise cause the prompt to happen, but happens to be some of the best document management features such as those that depend on WebDAV (Explorer View) and ActiveX (Multiple Document Upload). The other option is to use Forms Based Authentication with Persistent cookies. Generally, writing a persistent cookie to the client browser has mixed feelings in regards to whether it is a viable security practice or not, however ASP.NET 2.0 cookies are by default considered to be tamper-proof and encrypted.
I have read that a lot of companies offer some sort of application optimizers or whatever, either way I am not up for a COTS solution since most clients would nix it anyways, I find OOB security solution frightening when the code isn’t given. I know you can use ISA to solve it, however I have only seen one other solutions to this which solved my stuff fine in an extranet scenario. ISA tends to be a problem as well for some organizations because although there are built in mechanisms that will assist you in securely publishing a web server, it requires extra hardware, requires knowledge of ISA, a architect to construct an instance of ISA, and a person to administrator ISA (for things such as Connectivity Verifiers and Link Translation tasks).
So, I tend to lean towards a VC++ ISAPI filter (could you achieve the same thing with ActiveX or XMLHTTP? I am not sure.) to intercept requests as they are piped into SharePoint, since an ISAPI filter will be able to inject whatever at various points during the life of a user request. Generally, you can tailor the ISAPI filter in order to build the same type of persistent cookies that are offered with FBA with Windows authentication schemes such as Basic or Integrated authentication across an extranet. This would be fairly easy to construct as the ISAPI filter could intercept the HTTP request as the user passed it in, if the cookie doesn’t exist create a new cookie with a session and GUID, if the cookie does exist extract the cookie GUID, and finally pass all of this great information by the use of the Authorization Header into the IIS web request stream.
While I am 100% certain this route works fine, writing unmanaged code is not particularly a lucrative options because most people (like me!) have been spoiled with managed for so long. It just sucks to go back to doing it in unmanaged, I really don’t like it (even with the help of being able to construct a skelton ISAPI filter.
To write an ISAPI filter for SharePoint, you are going to have to investigate constructing at least two entry points GetFilterVersion and HttpFilterProc. GetFilterVersion is the primary entry point for your ISAPI filter taking HTTP_FILTER_VERSION structure as a parameter, it will determine the web request notifications that will be tripped by your ISAPI filter , such as if its for preprocess headers (as is the example below) and priority flags that should be related. Basically, it tells the filter what to listen for, as well as setting up an initial first time calls.
- BOOL WINAPI GetFilterVersion(
- PHTTP_FILTER_VERSION pVer
- if (pVer != NULL)
- pVer->dwFilterVersion = HTTP_FILTER_REVISION;
- pVer->dwFlags = SF_NOTIFY_PREPROC_HEADERS | SF_NOTIFY_ORDER_HIGH |
- SF_NOTIFY_NONSECURE_PORT | SF_NOTIFY_SECURE_PORT;
- return TRUE;
The other entry point that you must define is HttpFilterProc taking HTTP_FILTER_CONTEXT structure as a parameter, which associates context information with the web request that is being intercepted. You will see that the notifications that are available with this entry point are rather large. This relates to GetFilterVersion because based on the notifications that sent massages the pieces in HttpFilterProc, HttpFilterProc is really where the fun starts to happen.
- DWORD WINAPI HttpFilterProc(
- PHTTP_FILTER_CONTEXT pfc,
- DWORD notificationType,
- LPVOID pvNotification
Anyways, that is a primer to ISAPI filter development, albeit a very much truncated one. Eventually, once I get the chance to re-code my authentication filter (since it sporadically unload itself for some reason) I will probably distribute it.