Kald af webservice med certifikat giver fejl
Jeg har en COM+ applikation, der konsumerer en webservice, som hentes via https med et certifikat. Problemet er, at jeg får fejlen:System.Exception: Exception calling method. The underlying connection was closed: The connection was closed unexpectedly. Server stack trace: at WebServiceRequestor.TDCServiceComponent.CallTDCWebService(String userName, String certName, String url, String pid, String cpr) at System.Runtime.Remoting.Messaging.StackBuilderSink.PrivateProcessMessage(MethodBase mb, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs) at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContext) Exception rethrown at [0]: at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) at WebServiceRequestor.TDCServiceComponent.CallTDCWebService(String userName, String certName, String url, String pid, String cpr) at Logon.SignaturLoginCPR.Page_Load(Object sender, EventArgs e) in c:\inetpub\wwwroot\BorgerWeb\Logon\SignaturLoginCPR.aspx.vb:line 129
Jeg har lavet en Policy-klasse, og bruger denne, således at certifikatet altid accepteres. Men alligevel får jeg fejlen. Koden ser således ud:
using System;
using System.Net;
using System.Web.Services;
using System.Security.Principal;
using System.EnterpriseServices;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
using WebServiceRequestor.dk.certifikat.pid;
//using WebServiceRequestor.WebReference1;
//using System.Security.Cryptography.Xml;
namespace WebServiceRequestor
{
/// <summary>
/// Summary description for TDCServiceComponent.
/// </summary>
// This class calls the web service that requires a certificate.
public class TDCServiceComponent : ServicedComponent
{
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
private extern static bool DuplicateToken(IntPtr ExistingTokenHandle,
int SECURITY_IMPERSONATION_LEVEL,
ref IntPtr DuplicateTokenHandle);
[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
private extern static bool CloseHandle(IntPtr handle);
// Calls the Web service that requires client certificates
// certFilepath points to the .cer file to use
// url is the Web service url
// operand1 and operand2 are the parameters to pass to the Web service
public bool CallTDCWebService(String userName, String certName,
String url, String pid, String cpr)
{
bool retVal = false;
// Need to duplicate the token. LoadUserProfile needs a token with
// TOKEN_IMPERSONATE and TOKEN_DUPLICATE.
const int SecurityImpersonation = 2;
IntPtr dupeTokenHandle = DupeToken(WindowsIdentity.GetCurrent().Token,
SecurityImpersonation);
if(IntPtr.Zero == dupeTokenHandle)
{
throw new Exception("Unable to duplicate token.");
}
// Load the profile.
ProfileManager.PROFILEINFO profile = new ProfileManager.PROFILEINFO();
profile.dwSize = 32;
profile.lpUserName = @userName;
retVal = ProfileManager.LoadUserProfile(dupeTokenHandle, ref profile);
if(false == retVal)
{
throw new Exception("EG TDCServiceComponent: Error loading user profile: " + @userName + " " +
Marshal.GetLastWin32Error());
}
// Instantiate the Web service proxy
System.Net.ServicePointManager.CertificatePolicy = new WebServiceRequestorPolicy();
Microsoft.Web.Services2.Security.X509.X509CertificateStore store =
Microsoft.Web.Services2.Security.X509.X509CertificateStore.LocalMachineStore(Microsoft.Web.Services2.Security.X509.X509CertificateStore.MyStore);
store.OpenRead();
Microsoft.Web.Services2.Security.X509.X509CertificateCollection col =
store.FindCertificateBySubjectString(certName);
Microsoft.Web.Services2.Security.X509.X509Certificate cert = null;
if(col.Count > 0)
{
cert = (Microsoft.Web.Services2.Security.X509.X509Certificate)col[0];
}
else
{
// TODO: Log error (no certificate found)
}
pidws svc = new pidws();
PIDRequest[] req = new PIDRequest[1] { new PIDRequest() };
svc.ClientCertificates.Add(cert);
PIDReply[] rep = null;
try
{
rep = svc.pid(req);
}
catch(Exception ex)
{
if(ex is WebException)
{
WebException we = ex as WebException;
WebResponse webResponse = we.Response;
throw new Exception("Exception calling method. " + ex.Message);
}
}
ProfileManager.UnloadUserProfile(WindowsIdentity.GetCurrent().Token,
profile.hProfile);
CloseHandle(dupeTokenHandle);
return rep[0].statusCode == "0";
}
private IntPtr DupeToken(IntPtr token, int Level)
{
IntPtr dupeTokenHandle = new IntPtr(0);
bool retVal = DuplicateToken(token, Level, ref dupeTokenHandle);
if (false == retVal)
{
return IntPtr.Zero;
}
return dupeTokenHandle;
}
} // end class
}
// End
Er der nogen, der har en god idé?