Select netTcpBinding
There are many methods to bind WCF, generally four of which are commonly used:
- WsHttpBinding
- BasicHttpBinding
- NetTcpBinding
- WsDualHttpBinding
Two of the four binding methods support duplex communication:
- WsDualHttpBinding
- NetTcpBinding
In my current projects, considering that the product environment is basically Intranet, and the data transmission efficiency is relatively high, there may be large data volumes and frequent service access, in addition, the real-time message module is involved in the project and requires support for WCF duplex communication. We chose netTcpBinding.
Security Solution
In general, the Intranet deployment uses the netTcpBinding method, while the Internet uses the wsHttpBinding binding that can be blocked by the firewall. Because the Intranet services are relatively secure, therefore, most of the WCF configurations use windows authentication.
<Message clientCredentialType = "Windows"/>
Of course, you can also use the certificate, user name, password, and other methods to control security. For a long time, I wanted to perform security control in the project and read a lot of information, however, we found that netTcpBinding has less information on security control. Many of them talk about wsHttpBinding and basicHttpBinding. So far, we have found two feasible security control solutions for user name and password verification:
- Rewrite the SOAP Header to pass the user name and password, but it is not safe because it is transmitted in plaintext.
- Use the security mechanism of WCF to rewrite the verification class for verification.
The first solution requires a restriction on the scope of execution when the client adds an identifier to the SOAP, which is not well abstracted into the factory class of Proxy:
var proxy = new Service.Service1Client(); string result = string.Empty; using (OperationContextScope scope =
new OperationContextScope(proxy.InnerChannel)) { MessageHeader header = MessageHeader.CreateHeader("myname", "myname_ns",
"myname_value"); OperationContext.Current.OutgoingMessageHeaders.Add(header); result = proxy.GetData(11); }
So I want to explore the internal security mechanism of WCF and find that in netTcpBinding mode, the user name and password are used for authentication.
And password encryption. WCF believes that the sensitive information such as the user name and password should be encrypted when transmitting SOAP. This solution adopts the X509 authentication method, x509 is described in detail on MSDN.
Here we use a Demo to understand the entire process.
Instance verification
First, we have a service
[ServiceContract] public interface IAddService {[OperationContract] string Login (string name);} public class AddService: IAddService {public string Login (string name) {if (OperationContext. current. serviceSecurityContext. primaryIdentity. isAuthenticated) {name + = "OK .... ";}return name ;}you noticed that one of the Login methods of this Service determines that this judgment is the process in which WCF internally passes username and password verification on the client.
We override the Validate method by Inheriting System. IdentityModel. Selectors. UserNamePasswordValidator,
User Name and
Password verification.
Public class Validator: System. identityModel. selectors. userNamePasswordValidator {public override void Validate (string userName, string password) {if (userName = "wengyuli" & password = "pwd") {}} service configuration file, the first is a BindingConfig node.
<Bindings> <netTcpBinding> <binding name = "netTcpBindConfig"> <security mode = "Message"> <message clientCredentialType = "UserName"/> </security> </binding> </netTcpBinding> </bindings> the Service segment must be configured normally.
<service behaviorConfiguration="MyBehavior" name="HostTcpTest.AddService">
IndingConfiguration = "netTcpBindConfig"> </endpoint> <endpoint address = "mex" binding = "mexTcpBinding" contract = "IMetadataExchange"> </endpoint> </service> is the service behavior configuration, plants or weather can be controlled.
<behavior name="MyBehavior" > <serviceMetadata/> <serviceDebug includeExceptionDetailInFaults="true" /> <dataContractSerializer maxItemsInObjectGraph="6553600"/> <serviceCredentials> <serviceCertificate storeName="My" findValue="MyServer"
X509FindType = "FindBySubjectName" storeLocation = "CurrentUser"/> <clientCertificate> <! -- Ziá? OK? § Yi °? Right? Customer? Producer end? ? Row D certificate? ? Certificate? ? Type o? What is the token in? Is a None --> <authentication certificateValidationMode = "None"/> </clientCertificate> <userNameAuthentication userNamePasswordValidationMode = "Custom" Signature = "HostTcpTest. validator, HostTcpTest "/> </serviceCredentials> </behavior>
After you finish this, note that the code above contains a part of the digital certificate, which is generated as follows:
makecert -sr localmachine -ss My -n CN=MyServer-sky exchange -pe –r
Reference the service in Clleit. After the proxy class is generated, you can write the code to access the service on the client:
Var proxy = new AddService. addServiceClient (); proxy. clientCredentials. userName. password = "asd123 ,. "; proxy. clientCredentials. userName. userName = "wengyuli"; Console. writeLine (proxy. login ("23"); let's start the project. Note that VS should be started as an administrator.We will find that there is an error, and there is a problem with service negotiation, so I re-configure it and finally I can, now share it:
When we use the preceding command:
When you copy this MyServer to the 'restricted root certificate authorization', the problem can be solved.
Follow-upI have no in-depth understanding of x509 certification, and I plan to write a blog post after in-depth understanding.
Attached DEMO download: http://files.cnblogs.com/wengyuli/TcpTest.rar