WSE (Web Services Enhancements) is Microsoft to launch functional enhancements in order to create more powerful and better web services through .NET. The latest version is now WSE2.0 (SP2). This article describes how to use a secure function enhancement part in WSE2.0 to achieve secure Web Services. WSE's security function enhancements is a WS-Security standard. This standard is the WebService its own security protocol, which is set by IBM, BEA, Microsoft, etc., so it can be implemented on .NET and Java systems.
I mainly based on WSE documentation and yourself (in fact, more than half of the document painting scoop, huh, huh), please point out. In addition, this is 2.0, which varies greatly compared to WSE1.0, especially in security.
There is also a little attention, in fact, there are two ways to achieve security through WSE: one is what we need to introduce by writing code; the other is to write a policy file (XML document), these two methods are essentially The security function is achieved by setting the delivery SOAP message, such as increasing user messages, adding decryption, signature verification, etc. But I am not familiar with the second approach, and there is no time study, I don't write, huh, huh.
First, use the username and password to verify the Web Services caller identity.
The principle is very simple: the client is extended through the SOAP, and the username and password (clear text or encryption) are added to the SOAP message, send it to the Web Services side; after the server receives the message, the user name and password are obtained from the message context, and then Perform authentication and other operations. Here is the implementation steps:
Client:
1. Add Microsoft.Web.Services2 and the web services reference to the client to access, there is nothing to say. Of course, these two references must be, you may also need to add additional references to the client.
2. Modify the local Proxy class generated from the Web Services reference, this class's code generates the Reference file in the reference. Open the Web Services reference folder you want to operate from the .NET Development Environment, open the Reference.cs or Reference.vb file in the Reference.map node on the resource manager on the right side of the .NET development environment. If you don't see these files, you may not display all files, you need to set "display all files" in the Solution Explorer or Command Menu Item. After finding the Reference file, open it, change the inheritance parent class of the class to Microsoft.Web.Services2.WebServicesClientProtocol. Because the Proxy class can access the SOAP extension provided by WSE. Note that if you update a reference to a web service, you need to re-put inheritance class.
3. Add user names and passwords through instances of the UserNameToken class. UserNameToken belongs to Microsoft.Web.Services2.security.Tokens namespace. Suppose Web Services's local proxy class name is WebServer.WebService, the username is UserName, the user password is UserPwd, the code can be as follows (VB.NET, the same):
'Generate local Proxy class instance
Dim Mywebserve as new Webserver.WebService
'Generate the UserNameToken class instance, write the username, user password, and password send mode in the instance
DIM UnToken As UserNameToken = New UserNameToken (Username, UserPwd, Password "Sets the SOAP message validity period to determine the possibility of re-use the message even after interception by other users, it is set to 30 seconds, but pay attention to different systems The problem of clock synchronization.
Mywebserv.requestsoapcontext.security.timestamp.ttlinseconds = 30
'Add UserNameToken instances in the SOAP message context
Mywebserv.requestsoapcontext.security.tokens.add (unnetken)
'WEBMETHOD for calling web services
MyWebserv.Webmethod
Here, the setting of the password transmission mode is required. The password transmission mode is an enumerated data: sendnone, sendhashed, sendPlaintext. Different passwords, sending the password, respectively, and sending the mouth, the above example is to send a plaintext. If you select SendNone, the server does not verify the password, this security level is very low, and if the service needs to sign the passable SOAP message sign, the client should separately provide a password to its signature; sendhashed means sending a password SHA- 1 Hash value, this situation is safe, which is also the best way to recommend Microsoft. However, it requires the server side to verify the user's identity by writing code and config files, and the specific verification method will tell; sendPlainText is password in a clear text, if this is taken, the UserNameToken in the above code It is best to encrypt, otherwise the password is easily intercepted. The encryption method will be discussed in detail later;
Server:
1. First add an element that configures WSE in Web Services, which is also .NET development system using WSE's most basic step. The WSE document says that this step is required if the service call end is an ASP.NET system. If it is a normal client program, it is not necessary to add this identity. But I tested that I still need to add this configuration even if the call end is a Client program. Here is a complete configuration document.
soapextensiontypes>
WebServices>
configure>
Of course, in general, you only need to add the
2. Configure the server call authentication behavior, which is optional. As mentioned earlier, user information has been added in the SOAP message coming over, and the work to do is to resolve this information, and then verify according to a certain rule, and return the result.
There are two options that have the above processing: First, let WSE automatically verify that our own code and configuration files don't need to do anything. In this case, the WSE takes out the username and password from the usernametoken inside, which is why the user password must be sent clearly under the automatic verification of the previously mentioned automatic verification, take out the username and After password, WSE is determined and verified based on the user of the Windows domain where the system is located. That is to say, WSE is traversed from the user list of the active directory, looking for a valid user user account that exists and the received username / password, if the matching user is not found, returns an error that the caller is not authorized. It can be seen that the application system and user needs to be tied to the Windows domain, lack flexibility and is not suitable for docking with the existing business system. Therefore, more in practical applications should be used in the following second method.
The core of this method is that Web Services is implemented by inheriting the UserNameTokenManager class and overloads the AuthenticateToken method.
A. First, declare a class that is inherited from UserNameTokenManager.
Public Class CustomUserNameTokenManager
Inherits UserNameTokenManager
There is an access question in this way, in order to access this class in order to access this class, you also need to add some access to the declaration. Because the level of assembly trusts that can access the unmanagedcode is relatively high, you can request access to this class to access unmanagedcode. The above statement becomes the following form:
Inherits UserNameTokenManager
Of course, you can also configure other privilege requirements, just change the Flags's SecurityPermissionFlag enumeration value.
b. Overload the AuthenticateToken method in the code. After receiving the SOAP message containing the USERNAMETOKEN instance, WSE will define usernametoken, and call the VerifyToken method, and the verifyToken method calls the AuthenticateToken method during the execution, this method returns a password value, WSE will take it with The password in UserNameToken is compared. If the password sent is a plain text (UserNameText), it is directly compared; if the password is the hash value (usernametoken.password = sendhashed), WSE will make a SHA-1 hash operation for this return value, and then The result is compared with the password in UserNameToken. If it is inconsistent, it is returned to the user's unauthorized error. The above process is all automated, so the work we have to do is to overload the AuthenticateToken method, and the correct user password is implemented, which is used for comparison and verification. This is actually equivalent to PasswordProvider in WSE1.0.
The logic implemented by the AUTHENTICATETOKEN method is determined by the system according to the specific requirements, such as looking for the corresponding user password according to the user name to the database, or from LDAP. Here, you will find the example on the WSE document, the returned password and the submitted username are the same. Protected Overrides Function AuthenticateToken (Byval UserName AS UserNameToken) AS String
'EnSure That The SoAP Message Sender Passed a UserNameToken.
IF username is nothing then
Throw New Argumentnullxception
END IF
'This is a very Simple provider.
'In Most Production Systems the Following Code
'Typically Consults An External Database of (UserName, Hash)
'PAIRS. For this example, IT is the utf-8
'Encoding of the user name.
Dim encodedusername as byte () = _
System.Text.Encoding.utf8.getbytes (username.username)
Return system.text.Encoding.utf8.getstring (encodedusername)
END FUNCTION
c. Configure the web.config file to inform Web Services which class use to verify the user's identity.
First, add the elements indicating that using WSE2 in the file:
TYPE = "Microsoft.Web.Services2.configuration.WebserviceSconfiguration, Microsoft.Web.Services2, Version = 2.0.0.0, Culture = neutral, publickeyToken = 31bf3856ad364e35" /> configsections> configure> It should be noted here that it is necessary to write Secondly configure usernametokenManager subclass Microsoft.Web.Services2> configure> The value of the TYPE attribute is held in one line, "MyNamespace.customUsernameTokenProvider" must be a class-level name that is derived, MyassemblyName is the assembly name. In addition, Version, Culture, and PublickeyToken can be omitted. In this way, we have completed the verification based on the username / password for the Web Service call. The implementation of various safety functions in the future is based on it. Second, use the username and password to sign the SOAP message Although the above process implements a Web Services user identity confirmation. However, it cannot guarantee that the SOAP message received by Web Services is sent by the declaration user, so in the actual application, the calling party is also required to make a signature of the SOAP message, and send the signature along with the message; the server receives the message After that, in addition to verifying the user identity, you need to make a certification in the signature. To determine that the message is not changed during the transmission, the verified user is a user signed a message. Client: Just add signing in the original client SOAP message, as shown below, the black body is a new Code: Mywebserv.requestsoapcontext.security.tokens.add (unnetken) Mywebserv.requestsoapcontext.security.eferences.add (new _ MessageSignature (unnetkeen)) MyWebserv.Webmethod The above code is that the client generates a signature according to the instance of UserNameToken, and then adds the signature in the SOAP message, which is the WS-Security extension SOAP message header. Server: In fact, the server does not need to change anything. As long as the SOAP message sent by the client contains a signature, the server automatically verifies the validity of the signature. The server first verifies the username / password, and then uses the client name delivered by the client and the password you obtained (WSE automatically gets the signature from the Windows Active Directory, or by the overloaded AuthenticateToken method). If the verification fails, the description message is changed during the transfer or is not currently called the user, and returns the corresponding error. This piece adds a function that determines if the SOAP contains the signature in the help documentation of the WSE. It is not necessary to get some relevant information of the signature. Interested friends can look at themselves. Third, use the certificate to verify the identity and sign the SOAP message There is an inherent disadvantage of using the username / password, so we also need to use a certificate to complete the authentication of the user's identity in some security requirements. About the basics of PKI / CA will not be introduced, you can see related information. First we need to configure the server to ensure that WSE can access the certificate and its private key. (As for the application, management and use of the certificate belong to the basics, this is not tailored) This is mainly in the Web Services end setting to ensure that the server can automatically complete some functions, and no user intervention is required. Add as follows security> Microsoft.Web.Services2> configure> The StoreLocation property is a certificate store that WSE accessible. Its optional value has two: "localmachine" and "currentuser", which represent native certificate storage and current user certificate storage. The currentuser is used here, and the StoreLocation default is localmachine. The configuration of several properties is as follows: VerifyTrust, whether to verify the certificate chain validity of the certificate used, default is true; the allowtestroot: Does the verification certificate CA is valid, this parameter is valid when verifytrust is true, default is false; ALOWREVOCATIONURLRETREVAL, whether the online verification certificate is revoked, it is valid when verifytrust is true, default is true; allowurlretrieval, whether to verify the certificate online Chain effectiveness, AllowRevocationURLRETRIEVAL, whether the certificate is revoked online. Client: Step 1, 2 is basically the same as the first section using the username / password. But you should add a reference here: Microsoft.Web.Services2.security.x509 3. Write code to get the certificate to use. I used a listView control to display the personal certificate in the current user certificate storage for users to choose. Of course, you can also use the certificate to be used as a certificate of the certificate. The ListView control name is LV_CERTLIST, which has two columns: certificate holder main body and the name of the issuer. DIM CERT AS X509CERTIFICATE Dim lvitem as listviewItem 'Open your personal certificate library from the current user certificate storage Certstore = X509certificatestore.currentuserstore (x509certificatestore.mystore) Certstore.Open () LV_CERTLIST.ITEMS.CLEAR () 'Traversing the certificate, write to the listview control For Each Cert In Certormore.certificates Lvitem = lv_certlist.items.add (cert.getname) Lvitem.Subitems.Add (cert.getissuername) lvitem.tag = lvitem.index Next ceert 4. Select the selected certificate to generate an instance of X509SecurityToken, which is the subclass of SecurityToken as the previous UserNameToken. DIM CERT AS X509CERTIFICATE DIM CERTTOKEN AS X509SecurityToken Dim Result As stringcert = certificateore.certificates (lv_certlist.selectedindices) 'Determine whether the selected certificate supports the signature, and whether the private key exists If ceert.supportsdigitalSignature and not (cert.key is nothing) THEN 'Traversing the certificate, write to the listview control CertToken = New X509SecurityToken (CERT) Dim Mywebserve as new Webserver.WebService Mywebserv.requestsoapcontext.security.timestamp.ttlinseconds = 30 'Add X509SecurityToken containing certification information Mywebserv.requestsoapContext.security.tokens.add (CertToken) 'Sign by the SOAP message using the certificate and write the result in the message Mywebserv.requestsoapcontext.security.eferences.add (new _ Messagesignature (CertToken)) 'Method for calling web services MyWebserv.Webmethod END IF Server: Similar to the message using the username / password signature, the server is also automatically verified for the signature validity. At the same time, the server will verify the validity of the certificate based on the attribute settings in the Fourth, encrypt SOAP messages using username and password In the first section, if the password in the UserNameToken instance is clear, it is best to send UserNameToken encrypted. Do the following changes in the first sessile code, the black body code is new: Mywebserv.requestsoapcontext.security.tokens.add (unnetken) Mywebserv.requestsoapcontext.security.eferences.add (new _ Microsoft.Web.Services2.security.encryptedData (unnetken)) MyWebserv.Webmethod The above code is that the client encrypts the SOAP message according to usernametoken, and then puts the secret text in the SOAP message, the specific WS-Security extension SOAP message header The server is automatically decrypted. The server first verifies the username / password, and then uses the client name delivered by the client and the password you receive (WSE automatically gets the Decryption data from the Windows Active Directory, or by the overloaded AuthenticateToken method). If it fails, it returns a corresponding error. This piece is also added to the function of determining whether the SOAP is encrypted on the help documentation of WSE. V. Use certificate to add SOAP message This is slightly more complex. According to the PKI asymmetric plus decryption principle, the client encrypted on the message needs to be obtained in advance, the certificate public key as the receiver's server, and the server must ensure that the private key corresponding to its certificate can be accessed. So we must first choose to set the certificate it used in the server. The principle is to enable the server to access the private key corresponding to its certificate. For web services developed based on ASP.NET, the default user who needs to be runtably gives an access to the certificate private key. WEB Services default users on IIS 6.0 is Network Service. In other cases, the user account is determined by the username property of the For web services, if the user is used by the default ASPNET, it is best to choose the certificate in the local storage (LocalMachine Store). Because the ASPNET user is automatically generated when installing ASP.NET, its password is no way to access. If the certificate is included in the current user storage (CurrentUser Store), the server is likely to access the private key. After the server sets the certificate, you will get the client to get this certificate and public key. There is a relationship with your business system and application needs, you can put it on the web to let users download and install them in advance; if the application is available to LDAP or CA. The client is as follows: Mywebserv.requestsoapContext.security.tokens.add (CertToken) Add encrypted results in 'SOAP messages Mywebserv.requestsoapcontext.security.eferences.add (new _ Microsoft.Web.Services2.security.encryptedData (CertToken)) MyWebserv.Webmethod After the server receives the encrypted SOAP message, the corresponding private key is automatically decrypted. If it fails, it returns a corresponding error. It can be seen that the difficulty of using the certificate plus decryption message is the selection and configuration of the certificate, especially the message receiver. In addition to supporting the above username / password, the WSE supports two tokens of X509 certificates. It also supports Kerberos Ticket, Security Context token, and user-defined tokens. Kerberos Ticket seems to be WSE's own content, there is no in the standard WS-Security, and only on Windows XP SP1 / SP2, Windows 2003 is supported. The security context token requires an context token service generation. The core of the user-defined token is to derive a user's own token class by SecurityToken, complete various security functions. In short, WSE is to use this token and extended SOAP messages to implement Web Services security.