views:

140

answers:

5

Hi -

I work on an IIS6/ASP.NET website that must "require client certificates" in the form of a smart card (specifically a Common Access Card). I need to create a few services to access various URLs on a timer to do things like update search indices, warm up Sharepoint pages, and other tasks.

How can this be done, given that the site doesn't allow access unless you have a certificate, which is on the smartcard? I have tried to load the certificate (.cer) and load it in like this:

HttpWebRequest request = (HttpWebRequest)
            WebRequest.Create("https://.../someURL.html");

const string certFilename = @"my.cer";
var cert = X509Certificate2.CreateFromCertFile(certFilename);
cert.Import(certFilename, "my pin", X509KeyStorageFlags.Exportable);
request.ClientCertificates.Add(cert);
HttpWebResponse response = (HttpWebResponse)
       request.GetResponse();

But I get a 403 Forbidden.

A: 

If you are using SharePoint 2010:

  1. Go to SharePoint Central Administration
  2. Go to Application Management > Manage Web Applications
  3. Highlight your front-facing SharePoint site.
  4. Select "Extend" from the top menu.

What this does is it creates a separate SharePoint site that uses the exact same configuration and content databases, but you can host it elsewhere, and secure it separately. This allows you to have your normal, secure SharePoint instance up which is completely locked down, but simultaneously host another version of it elsewhere that has different security, which you can give other access to, namely your service that needs to run indexes or other jobs.

Ryan Hayes
@Ryan Hayes: Interesting. I'm using Sharepoint 2003, not 2010 unfortunately. And I actually need to hit multiple URLs in the site, not JUST Sharepoint's search indexing.
Scott Stafford
A: 

Can I just give a self-signed cert to the warmup daemon?

Scott Stafford
A: 

You can load your cert from your personal store as follows:

 System.Security.Cryptography.X509Certificates.X509Certificate cert = FindCertByName(PART_AFTER_CN_IN_CERT_SUBJECT);
request.ClientCertificates.Add(cert);

..

        private System.Security.Cryptography.X509Certificates.X509Certificate FindCertByName(string simpleName)
        {
            X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadOnly);
            foreach (X509Certificate cert in store.Certificates)
            {
                if( cert.Subject.Contains("CN="+simpleName))
                {
                    return cert;
                }
            }

            string msg = "The '" + simpleName + "' security certificate is not installed on this system!";
            throw new ApplicationException(msg);
        }
PerlDev
@PerlDev: So in this system there is a smartcard, how does that relate? Do I need the card somehow as part of the process, or can I just copy the .cer off?
Scott Stafford
You can export the cert to .cer file and loaded from file
PerlDev
A: 

Have you tried adding the X509 to the credentials cache? Example:

X509Certificate cert = new X509Certificate("sslCert.txt"); X509CertificateCollection certColl = new X509CertificateCollection(); certColl.Add(cert); CredentialCache credCache = new CredentialCache(); credCache.Add(new Uri(string.Concat(outputReport.reportURI)), "Basic", new NetworkCredential(NexConfig.User, NexConfig.Pass)); wr.AllowAutoRedirect = false; wr.ClientCertificates = certColl; wr.Credentials = credCache; HttpWebResponse resp = (HttpWebResponse)wr.GetResponse();

Jason M
@PerlDev: So in this system there is a smartcard, how does that relate? Do I need the card somehow as part of the process, or can I just copy the .cer off?
Scott Stafford
I would read the x509 out of the smartcard in that case, which you should be able to do if you have the right token-driver
Jason M
+1  A: 

This isn't an answer but I don't have enough rep to comment. The .cer doesn't hold the private key, that is just the public certificate so you can't use that. You need to load the private key directly from the smart card. I believe that may involve creating CSP params with the CSP name of the smart card reader, and then load the x509 cert with private key from the card directly. As far as I know the private key won't automatically be installed to the current user or current machine's MY store so you won't be able to load it from there. Don't have any code sorry.

Spencer
@Spencer: Is the PIN the private key? I think not, but then how does the PIN relate to the public/private key?
Scott Stafford