Okay, so we have a legacy ASMX web service that is currently running in .NET 3.5 and we're using Visual Studio 2008.
The problem is, we need to add authentication and would like to take advantage of the WS-Security model without breaking any existing internal clients who don't need to authenticate currently.
We've thought about adding custom headers, but that's not very WS-Security-ish. Also upgrading to WCF, while a long term goal, is not viable in the short-term.
Is there a way to access the UsernameToken (provided it's passed by the client) indirectly in the soap header of a VS2008 ASMX web service?
You could try Web Services Enhancements (WSE) 3.0. This adds support for an old version of WS-Security (the 2004 version I think - WCF supports the 2005 and 2007 versions). It sits on top of ASMX without disturbing it, and does still work in .NET 3.5 / WS2008.
Now for the downsides:
Example
Specifying credentials on the client:
void SetUsernameCredential(WebServicesClientProtocol service, string userName, string password) {
UsernameToken token = new UsernameToken(userName, password, PasswordOption.SendHashed);
service.SetClientCredential(token);
}
Authenticating credentials on the server:
public class MyUsernameTokenManager : UsernameTokenManager {
protected override string AuthenticateToken(UsernameToken token) {
// Authenticate here.
// If succeess, return an authenticated IPrincipal and the user's 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;