Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I'm currently struggling a little with the security layer of a web service I'm writing using WSS4J and CXF.

We obviously do not wish to store plaintext passwords in our backend, but would prefer to persist only salted hashes.

The service specifications, however, are preset by our client (who will be using the service to push a bunch of data our way), down to the use of UsernameTokens with plaintext password (All communication is SSL encrypted)

Now the problem I'm facing is that I cannot seem to find a way to hash the plaintext password from the request security header on our end, match it against our records along with the username and authorise or decline the request.

Every single guide, tutorial or example project I've found so far relies on a CallbackHandler configured as input interceptor, which requires retrieving the correct plaintext password, which is then matched against the supplied credentials directly. Not an option if we only store the hash. A couple of sources I came across that were trying to solve similar problems merely recommended to force the client to do the hashing. But as I stated above, this is not possible in our case. The service specifications are clear on the matter and it's out of our hands.

This particularly interesting sounding thread sadly didn't help me either: How to implement WSS UsernameToken when password on the server is salted and hashed?

Surely there must be another way than a WSS4JInInterceptor/CallbackHandler, one that will allow me to digest the received plaintext password and check it against the salted hash in our database.

Any pointers would really be greatly appreciated. Thanks.

share|improve this question
    
As this is highly specific, I would recommend asking on the Apache CXF mailing list. You're likely to get a much better response there. If you do find an answer outside the site, it'd be great if you could post it here and self-accept. –  Polynomial Jun 24 '13 at 11:42

1 Answer 1

up vote 1 down vote accepted

Thanks to Ivan Brencsics from the CXF mailing list for providing this hint. He writes:

If I understand correctly your question, your problem is that you dont [can't] access the password in the CallbackHandler, so you cannot hash it and compare it with the database.

I ran into the same problem recently, and I solved it by registering an org.apache.ws.security.validate.Validator instead of a CallbackHandler.

So for instance:

<jaxws:endpoint ...>
  <jaxws:properties>
    <entry key="ws-security.ut.validator" value-ref="sqlTokenValidator"/>
  </jaxws:properties>
</jaxws:endpoint>
...
<bean id="sqlTokenValidator" class="org.my.SqlTokenValidator"/>

and finally SqlTokenValidator:

public class SqlTokenValidator implements org.apache.ws.security.validate.Validator {

@Override
public Credential validate(Credential credential, RequestData data) 
throws WSSecurityException {
    ...
    UsernameToken usernameToken = credential.getUsernametoken();

    String username = usernameToken.getName();
    String password = usernameToken.getPassword();

   ... hash the password
   ... sql_auth(username, hash password)
   ... if failed throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION);

    return credential;
}

Oh and thanks to Polynomial for suggesting I check out the CXF mailing list. Still don't quite see the appeal of mailing lists over a proper forum ;)

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.