Avatar billede benjax Nybegynder
18. august 2005 - 16:06 Der er 3 kommentarer

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é?
Avatar billede benjax Nybegynder
18. august 2005 - 16:07 #1
Vi tager også lige Policy-klassen her:

using System.Net;
using System.Security.Cryptography.X509Certificates;

public class WebServiceRequestorPolicy : ICertificatePolicy
{
    public bool CheckValidationResult(
        ServicePoint srvPoint
        , X509Certificate certificate
        , WebRequest request
        , int certificateProblem)
    {

        //Return True to force the certificate to be accepted.
        return true;

    } // end CheckValidationResult
}
Avatar billede bjarkekr Nybegynder
01. februar 2006 - 13:06 #2
Har du fundet en løsning på problemet??
Avatar billede benjax Nybegynder
03. februar 2006 - 21:19 #3
Desværre, ingen løsning i C#. Jeg har måttet bruge en JAVA-baseret løsning i stedet - dér virker det.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester