私は以前の投稿で間違った質問をしていました。私は安全なWebサイト(https://..)として動作しているX.509証明書でセキュリティ保護されたWebサービスを持っています。会社のルートCAが発行したクライアントのマシン証明書(X.509)を使用して、クライアントマシンがサービスを使用することが許可されていることをサーバーに確認します。これを行うためには、私は証明書を検査し、特定の特徴を探し、その値をデータベースに格納された値(サムプリント?)と照合する必要があります。ここで WebサービスでクライアントからX509Certificateを送信するにはどうすればよいですか?
は( http://msdn.microsoft.com/en-us/magazine/cc163454.aspxからまっすぐ持ち上げた)私は、ローカル証明書ストアから証明書を取得するために使用するコードです:public static class SecurityCertificate
{
private static X509Certificate2 _certificate = null;
public static X509Certificate2 Certificate
{
get { return _certificate; }
}
public static bool LoadCertificate()
{
// get thumbprint from app.config
string thumbPrint = Properties.Settings.Default.Thumbprint;
if (string.IsNullOrEmpty(thumbPrint))
{
// if no thumbprint on file, user must select certificate to use
_certificate = PickCertificate(StoreLocation.LocalMachine, StoreName.My);
if (null != _certificate)
{
// show certificate details dialog
X509Certificate2UI.DisplayCertificate(_certificate);
Properties.Settings.Default.Thumbprint = _certificate.Thumbprint;
Properties.Settings.Default.Save();
}
}
else
{
_certificate = FindCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, thumbPrint);
}
if (null == _certificate)
{
MessageBox.Show("You must have a valid machine certificate to use STS.");
return false;
}
return true;
}
private static X509Certificate2 PickCertificate(StoreLocation location, StoreName name)
{
X509Store store = new X509Store(name, location);
try
{
// create and open store for read-only access
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection coll = store.Certificates.Find(X509FindType.FindByIssuerName, STSClientConstants.NBCCA, true);
if (0 == coll.Count)
{
MessageBox.Show("No valid machine certificate found - please contact tech support.");
return null;
}
// pick a certificate from the store
coll = null;
while (null == coll || 0 == coll.Count)
{
coll = X509Certificate2UI.SelectFromCollection(
store.Certificates, "Local Machine Certificates",
"Select one", X509SelectionFlag.SingleSelection);
}
// return first certificate found
return coll[ 0 ];
}
// always close the store
finally { store.Close(); }
}
private static X509Certificate2 FindCertificate(StoreLocation location, StoreName name, X509FindType findType, string findValue)
{
X509Store store = new X509Store(name, location);
try
{
// create and open store for read-only access
store.Open(OpenFlags.ReadOnly);
// search store
X509Certificate2Collection col = store.Certificates.Find(findType, findValue, true);
// return first certificate found
return col[ 0 ];
}
// always close the store
finally { store.Close(); }
}
その後、私は以下のようなものを発信ストリームに証明書を添付:
public static class ServiceDataAccess
{
private static STSWebService _stsWebService = new STSWebService();
public static DataSet GetData(Dictionary<string,string> DictParam, string action)
{
// add the machine certificate here, the first web service call made by the program (only called once)
_stsWebService.ClientCertificates.Add(SecurityCertificate.Certificate);
// rest of web service call here...
}
}
私の質問はこれです - どのようにWebサービスコードの証明書を "取得"するのですか?私がカスタム検証を行う方法をカバーしているほとんどのサンプルコードスニペットは、そこにGetCertificate()コールがあります。
メインクラスはWebServiceを継承しているので、Context.Request.ClientCertificateを使用して証明書を取得できますが、これはX509Certificate2ではなくHttpClientCertificateです。 HttpContextは私に同じ結果を与えます。他のアプローチはすべて、Webコンフィグレーションコードを使用して事前定義された検証コードを呼び出しますが、カスタムC#メソッドを呼び出して検証を行う方法のヒントはありません。
誰かが戻ってきて「見て、ちょうどこれをやって、うまくいく」という別の「愚かな質問」だと確信していますが、それでも問題ありません。私はこれを働かせるために何時間も費やしてきましたが、私の誇りは現時点ではほとんど存在しません。誰かが私の方法の誤りを私に見せてくれる?
おかげで、 デイブ
HttpContextをお持ちでない場合は、http:// stackoverflowの回答を参照してください。com/questions/7528455/how-to-get-the-x509certificate-from-a-client-request?lq = 1 –