我尝试设置内置身份验证的WCF服务。我想使用自定义UserNamePasswordValidator
来验证邮件中发送的凭据。
如果我使用标准wsHttpBinding
,我可以使用以下配置正常运行:
<wsHttpBinding>
<binding name="wsHttpBinding_Default" maxReceivedMessageSize="2147483647">
<security mode="Message">
<message clientCredentialType="UserName" establishSecurityContext="false" negotiateServiceCredential="false" />
</security>
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
</binding>
</wsHttpBinding>
使用SoapUI作为我的测试客户端,我可以通过在WSS-Password Type
设置为PasswordText
的情况下发送用户名和密码来启动验证器。
但是,这会在明文中发送用户名和密码。并且WCF不接受任何问题。这是一个示例请求:
POST https://localhost/AuthenticationService/AuthenticationService.svc HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/soap+xml;charset=UTF-8;action="http://tempuri.org/IAuthenticationService/GetIdentity"
Content-Length: 1060
Host: localhost
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:tem="http://tempuri.org/">
<soap:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
<wsse:Security soap:mustUnderstand="true" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-F5AF0BFF1621013979151869690921760">
<wsse:Username>test</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">test</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">LoAQmA/vE33hxFD/nDsBrA==</wsse:Nonce>
<wsu:Created>2018-02-15T12:15:09.217Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
<wsa:Action>http://tempuri.org/IAuthenticationService/GetIdentity</wsa:Action>
</soap:Header>
<soap:Body>
<tem:GetIdentity/>
</soap:Body>
</soap:Envelope>
所以在我看来,WCF忽略了消息安全部分。我的理解是,WCF消息安全性中的每条消息都应该加密和签名。
是的,我知道我可以使用传输安全性并将其称为一天,但这是指向安全而不是端到端。我真的不希望在流程的任何一点以明文形式显示凭证。
如何阻止WCF允许这些请求?
编辑:我现在已在服务行为中指定了客户端证书:
<serviceBehaviors>
<behavior name="AuthenticationServiceBehaviour">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<serviceCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" findValue="0e0bab25486677f12fc8abdf1345e5313aec4f67"/>
<clientCertificate>
<authentication certificateValidationMode="ChainTrust" trustedStoreLocation="LocalMachine"/>
<certificate storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" findValue="0e0bab25486677f12fc8abdf1345e5313aec4f67"/>
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
我得到了相同的结果,WCF仍盲目地接受明文消息。
要明确的是,如果我使用.NET服务引用生成的客户端,它会正确地进行加密和签名(通过fiddler查看跟踪来确认),因此消息安全性似乎确实有效。但是,我的问题是它仍然允许并响应不安全的消息。