Weird Issue with PocketSOAP in Classic ASP and IIS7 April, 2009
I'm doing due diligence on our new SOAP API and seeing what platforms can access it and also get a feel for how it is to use our API from different platforms. Unfortunately there are still a lot of Classic ASP developers/companies out there so I'm trying to see if they can use our SOAP interface or it they will have to just use our REST interface (Not really a bad thing actually, REST rocks, but sometimes clients want to use a specific technology). The only COM SOAP library I could find that supports SOAP 1.2 (Which is what our services are speaking) is PocketSOAP. Although I ran into a weird problem using it in Classic ASP on IIS7. When I would hit a service running over SSL I would get the following error:
Pocket.HTTP.1 error '80070005'
Error opening CertificateStore
/soap.asp, line 26
Struggled with this for a while and dug up a post from the PocketSOAP developer where he posts the actual source code that causes the error:
// Open the "MY" certificate store, which is where Internet Explorer // stores its client certificates.m_hMyCertStore = CertOpenSystemStore(0, _T("MY")); if(!m_hMyCertStore) hr = AtlReportError( CLSID_CoPocketHTTP, OLESTR("Error opening CertificateStore"), IID_NULL, HRESULT_FROM_WIN32(GetLastError())); else m_SslInitDone = true;
Classic ASP automatically impersonates, so if you enabled anonymous access in IIS7 the anonymous user defaults to the new built in account IUSR. If you used this default, authorization will be done under IUSR but since Classic ASP always impersonates, the code will also execute as IUSR (Whereas .NET does not default to impersonation and in this scenario authorization will be done as the IUSR and the code will execute as the app pool identity which is by default NetworkService). It doesn't appear that a user profile is ever loaded for the IUSR account so the call above is actually accessing the Default user "My" cert store (See below). The IUSR account doesn't have access to this so it fails. So there are a couple of ways to get around this; one is setting the anonymous account to be either the same as the app pool identity or a custom anon user account. In this case the user profile is loaded and the call above succeeds since the "My" cert store is in the user profile which gets loaded and the account has access to it (BTW, the loading of the app pool identity user profile can be toggled so it would need to be on, which is the default). The second way would be to give the IUSR account read/write/delete access the Default user profile cert store, but this doesn't seem like a very good idea to me since this is used as a template for new user profiles.
Hope this saves someone some time!