Browse DevX
Sign up for e-mail newsletters from DevX


WSE 2.0: Get Your .NET Web Services Security Up to Spec : Page 2

Microsoft's Web Services Enhancements for .NET (WSE) 2.0 toolkit improves existing specifications such as WS-Security. This article examines its WS-Security improvements and shows how you can upgrade your Web services to WSE 2.0.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

User Authentication
Not only can you use tWSE 2.0to encrypt and sign SOAP messages independently of the transport protocol, it also enables you to attach user credentials in a standardized way. The WSE uses security tokens internally to represent security claims from Web service methods. A UsernameToken is used to attach information about the user to the SOAP message, for example. With this token, the WSE can authenticate the user, validate the password, and check whether the user has all rights to execute the Web service method.

To use WSE functionality on the client side, you have to add a reference to the assembly Microsoft.Web.Services, which is installed in the GAC of the local computer. Furthermore, you have to change the base class of the Web service proxy to Microsoft.Web.Services.WebServicesClientProtocol. The client then has more properties (such as SoapContext) available for manipulating the SOAP message. The following listing shows how a UsernameToken can be attached to a SOAP message:

using Microsoft.Web.Services; using Microsoft.Web.Services.Security; UsernameToken token = new UsernameToken("JohnDoe", "Password", PasswordOption.SendPlainText); PDCRegistration proxy = new PDCRegistration(); proxy.RequestSoapContext.Security.Tokens.Add(token); SignupRequest request = new SignupRequest(); request.Address = "Microsoft One Way"; request.CreditCardNumber = "123"; request.Name = "Klaus Aschenbrenner"; SignupResponse reponse = proxy.SingupForPDC_UsernameToken(request); Console.WriteLine(response.RegistrationNumber);

The SOAP message with the UsernameToken is then sent to the Web service endpoint, where it must be determined whether the indicated user in the UsernameToken can be authenticated. For this server-side task, you can use the class UsernameTokenManager, which is implemented in the namespace Microsoft.Web.Services.Security.Tokens. To authenticate a user, you must derive only your own class from UsernameTokenManager and override the function AuthenticateToken. The function AuthenticateToken is called on the server side from the WSE when a SOAP message with a UsernameToken is received. This function's only task is to return the correct password for the user specified in the UsernameToken. If the password returned and the password specified in the UsernameToken are the same, then the SOAP message is processed. Otherwise, the SOAP message is rejected.

To use the WSE on the server side for your Web service, you must register a SoapExtension that ships with the WSE. To do this, you must register the SoapExtension in the section <soapExtensionTypes> in the web.config file of your Web service. After this step, your derived UsernameTokenManager must be registered within the WSE. The registration of the WSE lies in your web.config file, as the following listing shows:

<configuration> <microsoft.web.services> <security> <securityTokenManager type= "SignupPDCUserCredentials.AuthenticationManager, SignupPDCUserCredentials" xmlns:wsse= "http://schemas.xmlsoap.org/ws/2002/12/secext" qname="wsse:UsernameToken" /> </security> </microsoft.web.services> </configuration>

You must write the value of the attribute type in the web.config file within one line. I have broken it into several lines only for better readability.

After successfully registering the UsernameTokenManager in the web.config file, you can implement the class as follows:

using Microsoft.Web.Services; using Microsoft.Web.Services.Security; using Microsoft.Web.Services.Security.Tokens; public class AuthenticationManager : UsernameTokenManager { protected override string AuthenticateToken( UsernameToken token) { if (token.Username =="JohnDoe") return "Password"; return ""; } }

As you can see, the function AuthenticateToken receives as a parameter the UsernameToken from the SOAP message. With the property UsernameToken.Username, you can determine the user name for which you must return the correct password. In my primitive implementation, I just return the hard-coded password of the user name JohnDoe. In a production Web service, you can determine the password from other resources like XML-Files, databases, LDAP directories, and so on.

The following listing shows the SOAP header for the UsernameToken, which is sent within the SOAP message to the Web service endpoint:

<soapEnvelope> <soapHeader> ... <wsse:Security> <wsse:UsernameToken xmlns:wsu="..." wsu:Id="..."> <wsse:Username>JohnDoe</wsse:Username> <wsse:Password>Password</wsse:Password> <wsse:nonce>...</wsse:nonce> <wsu:Created>...</wsu:Created> </wsse:UsernameToken> </wsse:Security> </soapHeader> <soap:Body> ... </soap:Body> </soapEnvelope>

As you can see, the password is sent in clear text. This is because of the option PasswordOption.SendPlainText in the client code. If you use this option, Microsoft recommends using a secure protocol like HTTPS. But you can also use the option PasswordOption.SendHashed to transfer the encrypted password across the wire.

Thanks for your registration, follow us on our social networks to keep up-to-date