WCF 包装过度,选项太多,一旦涉及安全,非常的难,反复了才搞出好几次只需签名不加密的网络服务。因为错误信息不够详细甚至误导。微软经常夹带私货,无视真正的企业需求,例如和java实施的安全网络服务互通,通常java实施的安全网络服务互通只需HTTPS和X.509签名。但是微软就是不告诉你如何实现这个,整天扯他妈的wsHttpBinding,网上都是一般东抄西抄的关于wsHttpBinding教学材料或者混蛋,非常难以找到用WCF去实习只需签名的网络服务的材料,气得你半死。我觉得wsHttpBinding用途不是很大,是微软的私货。
有两点折磨了我好长时间,因为断断续续的实用WCF,半桶水晃荡。
1)PeerTrust:The certificate is valid if it is in the trusted people store. 我把它记成Personal Store即 My,老遇到 至少有一个Certificate无效的问题,困恼了很长时间。
2)千万不要用“using” 配合WCF Channel/Client/ChannelFactory,出错时真的是误导啊!痛心不已!
要不然出错时老出这个恶心的误导:
failed: System.ServiceModel.CommunicationObjectFaultedException : The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state. Server stack trace: at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout) Exception rethrown at [0]: at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) at System.ServiceModel.ICommunicationObject.Close(TimeSpan timeout) at System.ServiceModel.ClientBase`1.System.ServiceModel.ICommunicationObject.Close(TimeSpan timeout) at System.ServiceModel.ClientBase`1.Close() at System.ServiceModel.ClientBase`1.System.IDisposable.Dispose()其实根本没有连接上服务器,但是不知为什么有 Server stack trace。
更详细的见 http://www.codeproject.com/Tips/197531/Do-not-use-using-for-WCF-Clients
实施步骤:
1.定义接口,要设置ProtectionLevel.Sign,表示只需签名,无需加密
[ServiceContract(ProtectionLevel =ProtectionLevel.Sign) ] public interface IService { [OperationContract] string GetData(int value); }
2. 定义实施类
public class Service : IService { public string GetData(int value) { return string.Format("You entered: {0}", value); } }
3. 制作client 和server 端的X.509 certificate
这个看看网上怎么用MakeCert.exe
4. 服务器端web。Config
<system.serviceModel> <services> <service name="Service" behaviorConfiguration="certificateBehavior"> <!-- Service Endpoints --> <endpoint address="" binding="basicHttpBinding" bindingConfiguration="bindingCertificate" contract="IService" > <!-- Upon deployment, the following identity element should be removed or replaced to reflect the identity under which the deployed service runs. If removed, WCF will infer an appropriate identity automatically. --> <identity> <dns value="192.168.5.95"/> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> </service> </services> <bindings> <basicHttpBinding> <binding name="bindingCertificate"> <security mode="Message"> <message clientCredentialType="Certificate"/> </security> </binding> </basicHttpBinding> </bindings> <behaviors> <serviceBehaviors> <behavior name="certificateBehavior"> <serviceMetadata httpGetEnabled="true" httpGetUrl=""/> <serviceAuthorization principalPermissionMode="None"/> <serviceCredentials> <clientCertificate> <authentication revocationMode="NoCheck" certificateValidationMode ="None"/> </clientCertificate> <serviceCertificate findValue="WCFService" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My"/> </serviceCredentials> <serviceDebug includeExceptionDetailInFaults="true"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>
5.客户端的app.Config配置
<system.serviceModel> <behaviors> <endpointBehaviors> <behavior name="NewBehavior0"> <clientCredentials> <clientCertificate findValue="WCFClient" x509FindType="FindBySubjectName" /> <serviceCertificate> <authentication revocationMode="NoCheck" /> </serviceCertificate> </clientCredentials> </behavior> </endpointBehaviors> </behaviors> <bindings> <customBinding> <binding name="BasicHttpBinding_IService" sendTimeout="00:05:00"> <security defaultAlgorithmSuite="Default" authenticationMode="MutualCertificate" requireDerivedKeys="false" securityHeaderLayout="Lax" includeTimestamp="true" messageProtectionOrder="SignBeforeEncrypt" messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10" requireSignatureConfirmation="false"> <localClientSettings detectReplays="true" /> <localServiceSettings detectReplays="true" /> </security> <textMessageEncoding messageVersion="Soap11" /> <httpTransport /> </binding> </customBinding> </bindings> <client> <endpoint address="http://192.168.5.95/jqtest/service.svc" binding="customBinding" bindingConfiguration="BasicHttpBinding_IService" contract="ServiceReference1.IService" name="BasicHttpBinding_IService" behaviorConfiguration="NewBehavior0"> <identity > <certificateReference findValue="WCFService" storeLocation ="CurrentUser" storeName ="My" x509FindType ="FindBySubjectName"/> <!--<dns value="192.168.5.95"/> --> </identity> </endpoint> </client> </system.serviceModel>
6. 客户端测试程序
先加载Service Reference,然后
try { ServiceClient client = new ServiceClient(); client.GetData(1); client.Close(); } catch (Exception ex) { Console.Error.WriteLine(ex); }
我运行过得到了正确的结果。
还有一些缺点,例如identity没有配置好,不知道在生产环境是不是简单一点,因为有域名。还需要两个X.509 certificates,这个还需要简化
Raw Soap Request
POST http://192.168.5.95/jqtest/service.svc HTTP/1.1 Content-Type: text/xml; charset=utf-8 SOAPAction: "http://tempuri.org/IService/GetData" Host: 192.168.5.95 Content-Length: 2689 Expect: 100-continue Connection: Keep-Alive <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <s:Header> <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <u:Timestamp u:Id="uuid-24e0db20-53b0-4d34-818e-fdcc62eb8029-1"> <u:Created>2013-09-23T21:55:07.637Z</u:Created> <u:Expires>2013-09-23T22:00:07.637Z</u:Expires> </u:Timestamp> <o:BinarySecurityToken u:Id="uuid-d8e1d8a0-b63f-422a-8310-5ebae6932f73-2" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">MIIBsTCCAV+gAwIBAgIQ7TyxyvewZ7NN/WaG0DiFwDAJBgUrDgMCHQUAMBYxFDASBgNVBAMTC1Jvb3QgQWdlbmN5MB4XDTEzMDkxODE2MTY0MloXDTM5MTIzMTIzNTk1OVowFDESMBAGA1UEAxMJV0NGQ2xpZW50MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7lJcoEpV6s+BYVdYfc/21yFBut8nTUx5EtHXEAomx4upgeuZse72c3yIQVu/mPg+GvbVfhHsalO99j0ttoNco53U7EFEapdt434Pqrwkeiy28lmA+0AYtVAknM0YSByNfZ/3ElnGjqy06Sds5znpEc4dTPTrskaAwMyglLGBsxwIDAQABo0swSTBHBgNVHQEEQDA+gBAS5AktBh0dTwCNYSHcFmRjoRgwFjEUMBIGA1UEAxMLUm9vdCBBZ2VuY3mCEAY3bACqAGSKEc+41KpcNfQwCQYFKw4DAh0FAANBAGNGPOUdO3gAJ2cISN4BJC9Wpm5UfqsaTPznxXC45AHksA8UCzMryqq4V0cB7rhjvccA9oDMLZkxfYSBkBdYgH4=</o:BinarySecurityToken> <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> <SignedInfo> <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> <Reference URI="#_1"> <Transforms> <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> </Transforms> <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <DigestValue>65ERoR9h4UgYatBlGT88N0dSTqk=</DigestValue> </Reference> <Reference URI="#uuid-24e0db20-53b0-4d34-818e-fdcc62eb8029-1"> <Transforms> <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> </Transforms> <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <DigestValue>YBX4WAjPRQ3/w+oikyGOyLRiQSc=</DigestValue> </Reference> </SignedInfo> <SignatureValue>ERppkcG2gGl6wGCVbI4vSPV0V/B2zwOWH77giUcsefFFzAzVHkoefv1TdjIDrPnJcVrfeUlJqn60IS3N1a/yg1MX+YRiRPtvpI+YDQzRCqXzhgZh0fA16wzVy1tVi+OLdrLpQxwBGt+tMY3Wv65skSiHzWqLfUQqfTmmqdwOr7M=</SignatureValue> <KeyInfo> <o:SecurityTokenReference> <o:Reference ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" URI="#uuid-d8e1d8a0-b63f-422a-8310-5ebae6932f73-2"/> </o:SecurityTokenReference> </KeyInfo> </Signature> </o:Security> </s:Header> <s:Body u:Id="_1"> <GetData xmlns="http://tempuri.org/"> <value>1</value> </GetData> </s:Body> </s:Envelope>
Raw Soap Response
HTTP/1.1 200 OK Content-Type: text/xml; charset=utf-8 Server: Microsoft-IIS/7.0 X-Powered-By: ASP.NET Date: Mon, 23 Sep 2013 21:54:54 GMT Content-Length: 1862 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <s:Header> <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <u:Timestamp u:Id="uuid-bd361f67-714a-4deb-8f9c-8a7d8954a8ef-1"> <u:Created>2013-09-23T21:54:54.197Z</u:Created> <u:Expires>2013-09-23T21:59:54.197Z</u:Expires> </u:Timestamp> <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> <SignedInfo> <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> <Reference URI="#_1"> <Transforms> <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> </Transforms> <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <DigestValue>EVvi+44ZpmFe3H+0tz7MfNmrHyI=</DigestValue> </Reference> <Reference URI="#uuid-bd361f67-714a-4deb-8f9c-8a7d8954a8ef-1"> <Transforms> <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> </Transforms> <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <DigestValue>M6CgzU5+kM8WBslUdy2Xr9v4TJY=</DigestValue> </Reference> </SignedInfo> <SignatureValue>VCb5v4zi3+YA2PCyfUWkSUKQXEInYkqBJivmzRK5jWGEpsJ3ZJfqkzAfk3//eWjT38vrHGGgUJwQRkPWLW69M7ue3S4Tn8UpNcyI2IzbklIoJBjCVtdwP7BqRsDwHRGsynJXHhNSHSllzLrTnWNs9fPH1aSvqOKhuNHgfMlNBcU=</SignatureValue> <KeyInfo> <o:SecurityTokenReference> <X509Data> <X509IssuerSerial> <X509IssuerName>CN=Root Agency</X509IssuerName> <X509SerialNumber>-32031604220717131174929833209954748223</X509SerialNumber> </X509IssuerSerial> </X509Data> </o:SecurityTokenReference> </KeyInfo> </Signature> </o:Security> </s:Header> <s:Body u:Id="_1"> <GetDataResponse xmlns="http://tempuri.org/"> <GetDataResult>You entered: 1</GetDataResult> </GetDataResponse> </s:Body> </s:Envelope>本文乃硬座宝发明人原创,如需转载请一定注明原文作者 硬座宝发明人 也。
- 1楼suannai03146分钟前
- 您的文章已被推荐到博客首页和个人页侧边栏推荐文章,感谢您的分享。