How to use WS-Security and Access UsernameToken from ASMX web service?

Ok, so we have an outdated ASMX web service that is currently running in .NET 3.5, and we are using Visual Studio 2008.

The problem is that we need to add authentication and would like to use the WS-Security model without breaking existing internal clients that do not need authentication at this time.

We thought about adding custom headers, but this is not very WS-Security-ish. In addition, updating to WCF, while a long-term goal, is not viable in the short term.

Is there a way to access the UsernameToken (if provided by the client) indirectly in the soap header of the ASMX VS2008 web service?

+4
source share
1 answer

You can try Web Services Enhancements (WSE) 3.0 . This adds support for the old version of WS-Security (2004 version, I think - WCF supports versions 2005 and 2007). It sits on top of ASMX without disturbing it and still works in .NET 3.5 / WS2008.

Now for the bottom sides:

  • VS2008 does not support adding or updating WSE-enabled web links in client code. He will happily create the regular ASMX proxy class, but not the additional WSE proxy class required for authentication. Any existing WSE proxy code that you have will compile OK, but will be deleted if you try to update the web link in the IDE. If you have a copy of VS2005, you can use it to support, or at least create a client-side web link.
  • AFAIK, the WSE WS Security implementation is 100% incompatible with WCF versions. You will need to do your own WCF compatibility testing to make sure.

Example

Specifying credentials for a client:

void SetUsernameCredential(WebServicesClientProtocol service, string userName, string password) { UsernameToken token = new UsernameToken(userName, password, PasswordOption.SendHashed); service.SetClientCredential(token); } 

Server credential authentication:

 public class MyUsernameTokenManager : UsernameTokenManager { protected override string AuthenticateToken(UsernameToken token) { // Authenticate here. // If succeess, return an authenticated IPrincipal and the user password as shown. // If failure, throw an exception of your choosing. token.Principal = principal; return password; } } 

Reading credentials on the server:

 IPrincipal principal = RequestSoapContext.Current.IdentityToken.Principal; 
+7
source

All Articles