Ok I think I am getting a bit closer, now.
 
If using plain password UT then I guess this will need to used over
HTTPs, as transmitting plain text passwords over HTTP is a security
risk.
 
If the password type is password digest (a hashed password) then WSS4J
UsernameTokenProcessor class processes the password completely
If the password is of type password text or any other unknown password
type UsernameTokenProcessor delegates the password validation to the
callback class.

So if we want to use a hashed password UT, then we need to lookup the
password from a store in my callbackhandler class and add this to the
WSPasswordCallback object.
Then the WSS4J  UsernameTokenProcessor would perform hash algorithm and
compare the result with the transmitted password.
 
Herein lies a little issue.  In the application I am working with the we
do not store the password  anywhere in its plain text form, and hence I
cannot add it to the WSPasswordCallback object for
it to be verfied by my PatientServiceValidateUserTokenHandler class.
 
Am I correct in my understanding of how this stuff works, so far ?
 
Thanks
K
________________________________

From: Farmah, Kam [mailto:[EMAIL PROTECTED] 
Sent: Tuesday 19 June 2007 16:26
To: [email protected]
Subject: [xfire-user] Ws-security UserToken Hashed Password




Hi, I am new to xfire and I am trying to get ws-sec implemented using
the supplied examples as the basis. 
I have a few questions regarding whether I am along the right lines, and
also a few conceptual questions: 

Here is my config: 
  <service> 
    <name>PatientServiceUTHP</name> 
    <namespace>http://ctms.perceptive.com/PatientServiceWss</namespace> 
 
<serviceClass>com.perceptive.ctms.service.PatientService</serviceClass> 
 
<implementationClass>com.perceptive.ctms.service.PatientServiceImpl</imp
lementationClass> 
    <inHandlers> 
      <handler handlerClass="org.codehaus.xfire.util.dom.DOMInHandler"
/> 
      <bean class="org.codehaus.xfire.security.wss4j.WSS4JInHandler"
xmlns=""> 
        <property name="properties"> 
          <props> 
            <prop key="action">UsernameToken</prop> 
            <prop
key="passwordCallbackClass">com.perceptive.ctms.service.PatientServicePa
sswordHandler</prop> 
          </props> 
        </property> 
      </bean> 
      <handler
handlerClass="com.perceptive.ctms.service.PatientServiceValidateUserToke
nHandler" /> 
      </inHandlers> 
    </service> 

My client is as follows (snippet): 
        Service serviceModel = new
ObjectServiceFactory().create(PatientService.class, 
 
"PatientService", 
 
PatientServiceClient.SERVICE_NAMESPACE, 
                                                                 null); 

        PatientService service = (PatientService) new
XFireProxyFactory().create(serviceModel,
PatientServiceClient.SERVICE_URL

 
+ serviceName); 

        Client client = ((XFireProxy)
Proxy.getInvocationHandler(service)).getClient(); 

        client.addOutHandler(new DOMOutHandler()); 
        Properties properties = new Properties(); 
        configureOutProperties(properties); 
        client.addOutHandler(new WSS4JOutHandler(properties)); 

        System.out.print("Looking for list of patients...."); 
        List patients = service.getByTrialUnit(269, "FRA", 1); 

The configureOutProperties() does the following: 
    protected void configureOutProperties(Properties properties) 
    { 
        // Action to perform : user token 
        properties.setProperty(WSHandlerConstants.ACTION,
WSHandlerConstants.USERNAME_TOKEN); 
        // Set password type to hashed 
        properties.setProperty(WSHandlerConstants.PASSWORD_TYPE,
WSConstants.PW_DIGEST); 
        // Username in keystore 
        properties.setProperty(WSHandlerConstants.USER, "pdi"); 
        // Used do retrive password for given user name 
        properties.setProperty(WSHandlerConstants.PW_CALLBACK_CLASS,
PatientServiceClientPasswordHandler.class.getName());

    } 

Client Password Hander class: 
public class PatientServiceClientPasswordHandler implements
CallbackHandler { 

  private Map passwords = new HashMap(); 

  public PatientServiceClientPasswordHandler() { 
    passwords.put("pdi", "pdi"); 
  } 

  public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException { 
    WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; 
    String id = pc.getIdentifer(); 
    pc.setPassword((String) passwords.get(id)); 
  } 

} 

Server Password Handler class(snippet): 
public class PatientServicePasswordHandler implements CallbackHandler  {


  public PatientServicePasswordHandler() { 
  } 

  private String username; 
  private String password; 

  public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException { 

    try { 

      WSPasswordCallback pc = (WSPasswordCallback)callbacks[0]; 
      int usage = pc.getUsage(); 

      //its plain text pwd 
      if (usage == WSPasswordCallback.USERNAME_TOKEN_UNKNOWN) { 
        username = pc.getIdentifer().toUpperCase(); 
        password = pc.getPassword().toUpperCase(); 
      } 

      //its a hashed pwd 
      if (usage == WSPasswordCallback.USERNAME_TOKEN) { 
        username = pc.getIdentifer().toUpperCase(); 
        .......... 
        ........... 

My Validate class: 
public class PatientServiceValidateUserTokenHandler 
    extends AbstractHandler 
{ 

   public void invoke(MessageContext context) 
        throws Exception 
    { 
        Vector result = (Vector)
context.getProperty(WSHandlerConstants.RECV_RESULTS); 
        for (int i = 0; i < result.size(); i++) 
        { 
            WSHandlerResult res = (WSHandlerResult) result.get(i); 
            for (int j = 0; j < res.getResults().size(); j++) 
            { 
                WSSecurityEngineResult secRes = (WSSecurityEngineResult)
res.getResults().get(j); 
                int action  = secRes.getAction(); 
                // USER TOKEN 
                if( (action &  WSConstants.UT )>0   ){ 
                WSUsernameTokenPrincipal principal =
(WSUsernameTokenPrincipal) secRes 
                        .getPrincipal(); 
                // Set user property to user from UT to allow response
encryption 
 
context.setProperty(WSHandlerConstants.ENCRYPTION_USER,principal.getName
()); 
                System.out.print("User : " + principal.getName() + "
password : " 
                                 + principal.getPassword() + "\n"); 
                } 
                // SIGNATURE 
                if( ( action & WSConstants.SIGN ) > 0 ){ 
                    X509Certificate cert = secRes.getCertificate(); 
                    X500Name principal = (X500Name)
secRes.getPrincipal(); 
                    // Do something whith cert 
                    System.out.print("Signature for : "  +
principal.getCommonName()); 
                } 
            } 
        } 
    } 
} 

Here are my questions 
Is the callBack handler only applicable to the client, as a mechnism to
prompt the user for a username/password pair? 
In my config I have a client callback class
(PatientServiceClientPasswordHandler), and then another serverside
callback class (PatientServicePasswordHandler) which is going to lookup
the password from some kind of password serverside store.

Is this correct ?  I see the book store example uses it both client side
(to add security to SOAP header), and serverside to provide the password
lookup, so the example works OK.

If this is correct then why when I try to use the PW_DIGEST is the
password not available, like it is when I call PW_TEXT? Ie during
validation the call to :

Vector result = (Vector)
context.getProperty(WSHandlerConstants.RECV_RESULTS); 
 returns null. 
So what really is the purpose of the
PatientServiceValidateUserTokenHandler ? 

I guess I don't quite understand the order of execution, so I
desperatley need some help and guidance on my approach. 


Thanks in advance.. 
Kam 

Reply via email to