c# - 使用带有 x509 证书的 IIS 托管 WCF 服务进行身份验证
问题描述
我有一个通过 https 托管在 IIS 中的 Web 服务。我能够从测试客户端应用程序连接到服务并返回结果。
我想查看请求中使用的证书,但服务器似乎没有这方面的记录。
我正在按照此处定义的方式执行 basicHttpBinding:
<basicHttpBinding>
<binding name="basicHttpBinding">
<security mode="Transport" />
</binding>
</basicHttpBinding>
在客户端代码中创建本地服务代理时,我因此附加了一个 x509 证书,其中 userCerts 是本地证书存储中证书的非空列表
var service = new WcfBasicServiceClient();
service.ClientCredentials.ClientCertificate.Certificate = userCerts[0];
double randomDouble = service.GetRandomDouble();
再次,呼叫通过服务。在服务器端,我正在尝试检查使用的证书。但是,这ServiceSecurityContext.Current.PrimaryIdentity
是一个通用身份。此外, theOperationContext.Current.ServiceSecurityContext.AuthorizationContext.ClaimSets
是一个空集。就好像服务器不知道所使用的证书一样。
var securityContext = ServiceSecurityContext.Current;
var primaryIdentity = securityContext.PrimaryIdentity;
Logger.Info("Primary Identity: " + primaryIdentity);
Logger.Info("auth type: " + primaryIdentity.AuthenticationType);
Logger.Info("name: " + primaryIdentity.Name);
// gets an empty list here
// https://stackoverflow.com/a/7528703/680268
if (OperationContext.Current.ServiceSecurityContext.AuthorizationContext.ClaimSets == null)
{
Logger.Warn("claimset service configured wrong");
return;
}
if (OperationContext.Current.ServiceSecurityContext.AuthorizationContext.ClaimSets.Count <= 0)
{
Logger.Warn("claimset empty - service configured wrong");
return;
}
var cert = ((X509CertificateClaimSet)OperationContext.Current.ServiceSecurityContext.
AuthorizationContext.ClaimSets[0]).X509Certificate;
Logger.Info("cert serial num: " + cert.SerialNumber);
Logger.Info("subj name: " + cert.SubjectName);
Logger.Info("thumb print: " + cert.Thumbprint);
另外,在 IIS 网站设置中,我在 SSL 设置下设置了“接受”,但没有启用“需要 SSL”。
我的服务有什么错误配置,它不接受客户端请求中的 x509 证书?
这是我的服务的 web.config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="httpsBinding" allowCookies="true" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="WcfServiceLibrary1.WcfBasicService">
<endpoint address="" binding="basicHttpBinding" contract="WcfServiceLibrary1.IWcfBasicService" name="basicHttpBinding" bindingConfiguration="httpsBinding">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information,
set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
编辑,我更新了我的 web.config 和 app.config 以指定证书的客户端凭据类型,但是尝试在客户端上进行调用时出现如下错误:
ErrorSystem.ServiceModel.Security.MessageSecurityException: The HTTP request was forbidden with client authentication scheme 'Anonymous'. ---> System.Net.WebException: The remote server returned an error: (403) Forbidden.
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
--- End of inner exception stack trace ---
Server stack trace:
at System.ServiceModel.Channels.HttpChannelUtilities.ValidateAuthentication(HttpWebRequest request, HttpWebResponse response, WebException responseException, HttpChannelFactory`1 factory)
at System.ServiceModel.Channels.HttpChannelUtilities.ValidateRequestReplyResponse(HttpWebRequest request, HttpWebResponse response, HttpChannelFactory`1 factory, WebException responseException, ChannelBinding channelBinding)
解决方案
推荐阅读
- html - 如何使“安全”留在图像中?
- sql - SQL 良好实践:NOT IN vs <>
- nested - 未定义的方法“to_f”用于...日期、Ruby on Rails、Paperclip - 不捕获 image_url 或渲染图像作为结果
- python - 在 Windows 上找不到烧瓶命令行工具
- ruby-on-rails - 如何使用rails 6安装expose-loader 3.0.0?
- java - 对具有深层嵌套数组的列表进行排序
- xcode - MacOS Kmp 无法安装 ktor 依赖
- fastify - 在任意函数中使用 fastify json 模式验证
- javascript - 开始输入时滚动到页面顶部
- vue.js - 观察路由变化来捕获用户认证状态是多余的吗?