You can notice that the username/password are clear (not encrypted). This means that everyone that can see this message can steal the password.
There are typically 3 ways to overcome this.
1. Sending the hashed password only:
Where the digest is calculated from the password, a timestamp and a nonce.
However this is not really secure. A hacker can use a dictionary attack to extract the password.
2. Protecting the username with SSL.
This is a valid option but is limited to HTTP web service only and denies us from some of the rich WS-Security options. There are some other transports which are inherently secured (like SSL passthrough of load balancers as F5's BIG-IP) but I will not discuss them here.
3. Protecting the username with message-level X.509 certificate.
This is another valid option but sometimes more complex to implement.
In practice if you want to use username/password you would need to decide between options 2&3. Some frameworks, like Microsoft's WCF, even prevents you from using option #1 at all. Nevertheless there are a few exceptions where option #1 is valid:
If you are using WCF and have the above needs you should use the WCF ClearUsernameBinding. What's next? get this blog rss updates or register for mail updates!
11 comments:
Who knows where to download XRumer 5.0 Palladium?
Help, please. All recommend this program to effectively advertise on the Internet, this is the best program!
Yaron,
Lots of great WCF info on your site.
On this page, you have an example of using the hashed PasswordDigest along with a username.
I am trying to call a Java web service with a WCF client that needs to conform to the following SOAP Headers. Do you have any examples of how to accomplish this??
<soapenv:Header>
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsu:Timestamp wsu:Id="Timestamp-29584084" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsu:Created>2008-07-09T20:28:37.412Z</wsu:Created>
<wsu:Expires>2008-07-09T20:28:47.412Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken wsu:Id="UsernameToken-482906" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>UserWebService</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">S5Of09Zuan02wWpbSEx7EDZsefE=</wsse:Password>
<wsse:Nonce>Ka+AC6oq5ROJ/pHX1sW+Ng==</wsse:Nonce>
<wsu:Created>2008-07-09T20:28:37.412Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
Hi Josh
There is no way to manipulate WCF API to omit this exact header as it does not support hashed password.
What you should do is inject this header into the message using a MessageInspector. The nonce should be a random base64 string of that size and the timestamps taken dynamically from the clock.
>>There is no way to manipulate WCF API to omit this exact header as it does not support hashed password.
Hi, Yaron. Have i understood u correctly and there is no way to authorize using digest in WCF?
Thing is i have a java WS with wsse authentication behind ssl and i need to write a client to communicate with it.
I've doing all the
b.Security.Transport.ClientCredentialType = HttpClientCredentialType.Digest;
sc.ClientCredentials.HttpDigest.ClientCredential = new NetworkCredential("a", "a").GetCredential(new Uri("host"), "Digest");
But password keeps being transfered as plain text : (. Is there a way to configure proxy for hashed password to be transferred?
You can do digest at the transport level. The problem is in the message level, which you do not need.
Use fiddler to see if the server really adks for digest from the client or only basic.
Thx for quick reply, Yaron!
I've tried swithing to Transport, but in this case according to Charles no wsse headers passed + server returnes
System.ServiceModel.FaultException: com.sun.xml.wss.XWSSecurityException: Message does not conform to configured policy [ AuthenticationTokenPolicy(S) ]: No Security Header found; nested exception is com.sun.xml.wss.XWSSecurityException: com.sun.xml.wss.XWSSecurityException: Message does not conform to configured policy [ AuthenticationTokenPolicy(S) ]: No Security Header found
I've checked with fiddler, and do not see any information regarding authentification mode. But when i use TransportWithMessageCredential wsse headers are passed correctly(though pass is a plain text) and i get
System.ServiceModel.Security.MessageSecurityException: An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail. ---> System.ServiceModel.FaultException: com.sun.xml.wss.XWSSecurityException: Receiver Requirement for Digested Password has not been met; nested exception is com.sun.xml.wss.XWSSecurityException: com.sun.xml.wss.XWSSecurityException: Receiver Requirement for Digested Password has not been met
Please publish how your request messagae should look like.
It should look like this(at least such request is coming from java clients and works from soapUI, basic auth is not working)
http://pastebin.com/2Pp55Kf3
app config
http://pastebin.com/bAA7tgnC
Code itself
http://pastebin.com/WWYhPzUh
Charles shows that request came like this
http://pastebin.com/5uUYndrw
Server responded with
http://pastebin.com/NgCXB0KM
WCF does not support digested password in the messgae level.
You might be able to add this with a custom header instead.
I would suggest you set up a working Java client and then see how the soap it sends looks like.
@Josh and @Marat, did you ever find a solution to your problem.? I have the same issue.
It is very frustrating to think that we have to revert to using obsolete WSE libraries so that we can get this to work.
All well and good that Microsoft thought that this was not worth supporting, but nobody told the swathes of corporations who still use this authentication scheme, and force us to deal with it.
If you found a solution that works with SCF, then I'd love to hear more. You'll find me on Twitter as @junto. http://twitter.com/junto
I would just be nice to know that this is possible, and that I'm not wasting my time trying to work towards something that is neigh on impossible to achieve!
Yep, Ben, finally, i've found the WCF solution, though a pretty ugly one :).
I'm creating Nonce, Created and hashed password digest myself and adding them into soap request headers by defining own inspector(header added in IClientMessageInspector.BeforeSendRequest) and behaviour(implements IEndpointBehavior) classes where i override soap headers.
I've spent about two weeks trying to find more elegant solution, but found none :)
Post a Comment