Preface:
WCF provides multiple transmission security modes, including none (without any security mechanisms), transport security, message security, and transportwithmessagecredential. there are many differences between transport security and message security. For example, message security is maintained on any number of nodes between the initial sender and the last receiver of the message, however, transmission security can only ensure transmission security between two nodes. In addition, compared with the transport security mode, messeage Security provides more mechanisms to verify the transmission source. For example, the client identity types provided by transport security include:None, basic, digest, windows, and certificateMessage security provides the following types of client authentication:None, windows, username, certificate, issuedtokenThis article describes how to use the username authentication mechanism in message security mode in combination with the server certificate to verify the customer's identity and ensure the security of transmitted data.
(For more information about the difference between transport security mode & message security mode, please refer to: http://msdn.microsoft.com/en-us/library/ms789011.aspx)
Body:
First, we introduce the username authentication mechanism in message security mode, as shown in:
The process is described as follows:
Step 1:
After a secure connection is established between the WCF client and the WCF Service, a Session Encryption supported by both parties is obtained through negotiation.Algorithm(Symmetric encryption algorithms, such as des) and session keys (this process is actually quite complex. For details about how to use certificate to establish a secure session, see other documents ), the username and password provided by the client are encrypted by the encryption key and then transmitted to the server.
Step 2:
The WCF Service provides a username-based validator. We often need to rewriteSystem. identitymodel. selectors. usernamepasswordvalidator's validate() Method to customize the authentication process. For example, we can verify the user legality in the database or whether the user can be mapped to a Windows domain account (the method for obtaining the user identity of the current security context is:
Windowsidentity identity = servicesecuritycontext. Current. windowsidentity ).
Step 3:
If the authentication is successful, you can continue the service of the client request and return response; otherwiseSystem. identitymodel. tokens. securitytokenexceptionAnd the connection is terminated.
Example:
1. First, we define a simple WCF Service.CodeAs follows:
Code
[Servicecontract (namespace = " Intern " )]
Public Interface Imymath
{
[Operationcontract]
Int Sum ( Int X, Int Y );
}
[Servicebehavior (instancecontextmode = Instancecontextmode. persession)]
Public Class Mymath: imymath
{
Public Mymath ()
{
Console. writeline ( " Mymath constructor is called " );
}
Public Int Sum ( Int X, Int Y)
{
Return X + Y;
}
}
2. Add app. config and configure it accordingly.
The key is to specify the security mode as message and set messageclientcredentialstype to username when configuring the protocol. As shown in:
Create a new servicebehavior configuration and set usernamepasswordauthenticationmode in usernameauthentication element to custom, as shown in:
Then we define a class that inherits from the abstract class system. identitymodel. selectors. usernamepasswordvalidator and override the abstract method of the base class: Validate (string username, string password). The Code is as follows:
Code
Public Class Myusernamepasswordvalidator: system. identitymodel. selectors. usernamepasswordvalidator
{
Public Override Void Validate ( String Username, String Password)
{
If (Username = " Herengang " && Password = " Herengang " )
{
Console. writeline ( " Welcome: {0} " , Username );
}
Else
Throw New System. identitymodel. tokens. securitytokenexception ( " Unknown username " );
}
}
Note: When you set customusernamepasswordvalidatortype, you have set it to the custom authentication class myusernamepasswordvalidator.
After the configuration is complete, click Run To see what appears?
ProgramThe following exception is thrown:
The channel dispatcher ' Http: // localhost: 8011/service/mymath ' With contacts (s) ' "Mymath" ' Is Unable to open its ichannellister.
God! What happened? When usernamepassword is used for client authencation, username and password cannot be transmitted in plain text over the network. Therefore, the server must provide a certificate to encrypt sessions. Otherwise, a secure channel listener cannot be created, leading to the above exception.
Therefore, the solution is to install a servicecertificate on the server. Then click Run. The expected WCF Service is online. Haha.
Now, create the WCF client.
After svcutil is used to obtain the Service proxy and App. config, add it to the client project. The client code is as follows:
Code
Mymathclient Client = New Mymathclient ();
Client. clientcredentials. username. Username = " Herengang " ;
Client. clientcredentials. username. Password = " Herengang " ;
Client. open ();
Console. writeline ( " 3 + 4 = {0} " , Client. sum ( 3 , 4 ));
Client. Close ();
Click Run.
The program throws an exception as follows:
Code
Soap security negotiation'Http: // localhost: 8011/service/mymath' ForTarget'Http: // localhost: 8011/service/mymath'Failed. See inner exceptionForMore details.
What happend?
The original certificate provided by the server cannot be verified by the client. That is to say, the client does not know the certificate provided by the server according to its certificateauthenticationmode (by default: chain Trust. Therefore, throw refers to the exception information of security negotiation. The solution is to change the certificateauthencationmode of the client to the Verification Mode that can be passed in the current mode, such as none (does not verify its validity at all) and custom (customize its validity, in this case, we need to customize a custom system. identitymodel. selectors. x509certificatevalidator class, and override abstract method validate (x509certificate2 certificate. For simplicity, this example is set to none.
In fact, in the username/password-Based Client Authentication mode, it is not necessary for the client to provide verification of the encrypted public key. However, when svcutil is used to obtain the client config file from the WCF Service, the encrypted Public Key is included in the config file to generate the client configuration file, in this way, the client does not need to install the encryption Public Key provided by the server. The client Public Key generated by the client is as follows:
Code
< Client >
< Endpoint address = " Http: // yourwcfserver/service/mymath " Behaviorconfiguration = " Newbehavior "
Binding = " Wshttpbinding " Bindingconfiguration = " Mymath " Contract = " Imymath "
Name = " Mymath " >
< Identity >
< Certificate encodedvalue = " Awaaaaeaaaauaaaaduowalhkukv2 + release/release + ofkoeh/fzgzbcjiio + release/release + release/ytpsyqwtd62l1vlz9q + release + nmos6cdwg = " />
</ Identity >
</ Endpoint >
</ Client >
As shown in:
OK. Click Run!
Run screenshot as follows:
Client:
Server: