Building secure .NET web services has never been much harder than building secure .NET web sites. To secure the network, you can employ SSL or TLS protocols; they work as expected and can be implemented in a rather hassle-free way. To secure the application layer, you can arrange a mechanism to authenticate and authorize callers and, at most, require that the payload is encrypted.
In theory, any of the three authentication methods supported by ASP.NET 2.0-Windows, Passport, and Forms-could be used to authenticate callers of .NET web services. In practice, Passport is hardly used because of the implications it has-joining the initiative, adhering to the required security and privacy standards, implementing an authentication layer based on the Passport SDK.
Both Windows and ASP.NET Forms authentication can be easily plugged into a web service to identify the user making the call. Windows authentication is not very practical for pure Internet applications because it requires the user to have an account on the server machine. When the number grows to the order of the thousands, it does pose some management and administrative issues. What is left? ASP.NET Forms authentication.
Mapped to web services, Forms authentication simply means a custom authentication model in which the web service gets the credentials and processes them to accept or deny the call.
To implement a custom authentication scheme for web services, you need to solve two issues-how to pass and verify credentials. Both things can be done in a variety of ways. And there's the rub. If Murphy wrote software, his first law would be "Anything that can be coded two different ways will be coded two different ways. That's why standard specifications like the WS-* family of specs are welcome; and that's why toolkits like Web Services Enhancements for Microsoft .NET (WSE) version 2.0 are needed.
WSE 2.0 widely supports two of the most mature WS-* standards, specifically WS-Security and WS-Policy. WS-Security allows developers to implement an authentication and authorization model using a standard set of SOAP headers and recognized best practices. WSE 2.0 supplies built-in classes to set up two authentication models and a role-based authorization scheme. Authentication comes in two flavors-Windows and custom. Credentials are passed using a standard SOAP header and can be of different types-username/password, Kerberos ticket, X.509 certificate, or anything else you code yourself, both binary or XML. To implement Windows authentication, you simply pass user name and clear password and use existing classes to manage the credentials. The password is checked against the account of the Windows (or Active Directory) account. To implement a custom model, you derive a new user token manager class from a base WSE 2.0 class and override the method that authenticates the token. The password in the credentials can be sent as clear text (required for Windows authentication) or hashed text. You can also send no password as long as you digitally sign the message. The signature will represent your proof-of-possession.
WS-Policy enables developers to use configuration files to specify requirements for receiving and sending messages. Those requirements, known as policy assertions, are expressed in a configuration file. The WSE 2.0 runtime checks SOAP messages to determine whether they comply with the policy assertions. WSE comes with a set of predefined assertions, such as the requirement that the message be signed. Custom assertions can be defined to define authorization and even to build a declarative validation layer around the web methods.
Dino Esposito is Wintellect's ADO.NET and XML expert, and a trainer and consultant
based in Rome, Italy. Dino is a contributing editor to Windows Developer
Network and MSDN Magazine, and the author of several books for Microsoft
Press including Building Web Solutions with ASP.NET and ADO.NET
and Applied XML Programming for .NET. Contact Dino at [email protected].