0

I've been spinning my wheels for a few days now not making any progress, and suggestions I've found thus far online haven't quite done the trick, so here goes:

  1. I have a WCF service which ties into... not sure what type of web service you'd call this on the other end, kind of REST-ish. The URL to the method looks like this "https://partner.someservice.com/SomeMethod.asp". I cram some query string args onto the end of that and POST the request to their server.

  2. The error in VS just shows 403, but when I've used Fiddler I see 403.7. Before importing the cert into my browsers I saw 403.7 as well. I can inspect my request object and see the ClientCertificates with [1] cert specified, so I'm pretty sure it is getting attached.

  3. I've imported the .pfx file into both my machine and local user cert stores. I've run the winhttpcertcfg utility a number of times in a number of ways, basically following the instructions I've seen on MSDN and SO posts.

    winhttpcertcfg -g -c LOCAL_MACHINE\MY -s [cert] -a [user/aspnet/auth'd users]

    winhttpcertcfg.exe -i [cert.pfx] -c LOCAL_MACHINE\MY -p [pwd]

  4. I've imported the .pfx file into Chrome. If I hit that URL in Chrome, I get a prompt to select my cert, and then I can proceed to the URL just fine. Same behavior in IE.

So this seems to be specific to me running in VS, although I'm not sure what option I haven't checked or what permission I haven't granted. Under project properties on my WCF service, I have tried "Use Visual Studio Development Server" and "Use Local IIS Web server" but get the same behavior from each. What am I missing?

Some code:

    private static string DoPost(string postData)
    {
        string result = null;

        var httpWebRequest = (HttpWebRequest)WebRequest.Create(GetEndpoint());
        var encoding = new ASCIIEncoding();
        var bytes = encoding.GetBytes(postData);

        httpWebRequest.Method = "POST";
        httpWebRequest.ContentType = "application/x-www-form-urlencoded";
        httpWebRequest.ContentLength = bytes.Length;
        httpWebRequest.ClientCertificates.Add(clientCertificate);

        using (var stream = httpWebRequest.GetRequestStream())
        {
            stream.Write(bytes, 0, bytes.Length);
            stream.Close();

            using (var httpWebResponse = httpWebRequest.GetResponse())
            using (var responseStream = httpWebResponse.GetResponseStream())
            {
                if (responseStream != null)
                {
                    using (var reader = new StreamReader(responseStream))
                    {
                        result = reader.ReadToEnd();
                    }
                }
            }
        }

        return result;
    }

And the code obtaining the cert (in a utility class written by another dev, and this seems to work just fine in production):

    public static X509Certificate2 GetCertificateBySerial(string serial)
    {
        var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
        store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);

        var certColl = store.Certificates.Find(X509FindType.FindBySerialNumber, serial, false);
        store.Close();

        if (certColl.Count == 0)
        {
            throw new Exception(String.Format("A certificate with a serial number of \"{0}\" is not installed on the server.", serial));
        }
        return certColl[0];
    }
4

1 回答 1

0

I made a couple of changes, and was able to get this to work. For one, I had to change from GET to POST*, and in doing so I accidentally left a portion of the endpoint/url in the post data (oops). Secondly, I included this in my httpWebRequest:

httpWebRequest.ProtocolVersion = HttpVersion.Version11;

And last, the 403.7 error is actually being caused by Fiddler intercepting my traffic. I don't have this cert properly configured in Fiddler, but that will come next. Once I shut down Fiddler and actually formatted my POST data properly, things worked out.

*Switching from GET to POST had nothing to do with getting this resolved, just some back story.

TL;DR I didn't format my request properly.

于 2013-05-13T21:26:17.337 回答