Hi,

To answer your first question: To fully understand the semantics of
processing an inbound UsernameToken, you need to examine the
implementation of
org.apache.ws.security.processor.UsernameTokenProcessor in WSS4J.
Basically, the implementation is as follows:

a) Digested Password: Get the original password from the CallbackHandler
implementation, process it accordingly and compare to the received
digested password.
b) Any other Password Type: Delegate all validation to the
CallbackHandler implementation.

So how you implement your CallbackHandler implementation depends on your
requirements. At the moment your implementation essentially does no
processing of the password. 

So to summarise, any code you have for comparing the password etc.
should be implemented in AuthenticationCallbackHandler, rather than in
your ValidateUserTokenInterceptor.

Colm.

-----Original Message-----
From: dmadunic [mailto:[EMAIL PROTECTED] 
Sent: 28 August 2007 11:14
To: [email protected]
Subject: WS-Security and CXF


Hi all,
i have two questions concerning how to implement WS-Security with CXF.

1) First question: how on the server side to read CallbackHandler
supplied
password?

Followoing instructions on CXF homesite and from several articles, I
have
created simple HelloWorldService and attached to it following
interceptors:

        <jaxws:endpoint  id="helloWorld"
implementor="demo.spring.HelloWorldImpl"
address="/HelloWorld" >
                <jaxws:inInterceptors>
                        <bean
class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor"/>
                        <bean
class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
                                <property name="properties">
                                        <map>
                                                <entry key="action"
value="UsernameToken"/>
                                                <entry
key="passwordType" value="PasswordText"/>
                                                <entry
key="passwordCallbackClass"
value="demo.interceptors.AuthenticationCallbackHandler"/>
                                        </map>
                                </property>
                        </bean>
                        <bean
class="demo.interceptors.ValidateUserTokenInterceptor"/>
                </jaxws:inInterceptors>

        </jaxws:endpoint>

AuthenticationCallbackHandler is very simple it just does the following:

public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
                WSPasswordCallback pc = (WSPasswordCallback)
callbacks[0];
                
                if (pc.getIdentifer().equals("joe")) {
                        pc.setPassword("password");
                }
        }

I also wrote my demo.interceptors.ValidateUserTokenInterceptor which
should
Validate received token. 

public void handleMessage(Message message) throws Fault {
                boolean userTokenValidated = false;

                logger.debug("Invoked - ValidateUserToken: " + message);

                //logger.debug("messagePwd: " + message.get);
                Vector result = (Vector)
message.getContextualProperty(WSHandlerConstants.RECV_RESULTS);

                if (result==null) {
                        throw new
IllegalArgumentException(WSHandlerConstants.RECV_RESULTS + "
Property not found in MessageContext?!");
                }

                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();
                                logger.debug("Checking: " + secRes);
                                // USER TOKEN
                                if ((action & WSConstants.UT) > 0) {
                                        WSUsernameTokenPrincipal
principal = (WSUsernameTokenPrincipal)
secRes.getPrincipal();
                                        logger.debug("name=" +
principal.getName());
                                        logger.debug("password=" +
principal.getPassword());
                                        logger.debug("passwordType=" +
principal.getPasswordType());
                                        logger.debug("createdTime=" +
principal.getCreatedTime());

                                        if (principal.getPassword() ==
null) {
                                                throw new
RuntimeException("Invalid Security Header");
                                        } else {
                                                // NOW COMPARE PASSWORDS
-
HOW????
                                                userTokenValidated =
true;
                                        }
                                }
                        }
                }
                if (!userTokenValidated) {
                        throw new RuntimeException("Security processing
failed");
                }
        }

So far i was able to read information from WSSE:Security header - ie.
username and pwd supplied by the Client. But i do not know how to
address
the password value supplied by AuthenticationCallbackHandler inside this
interceptor??

2) Second question: how to properly configure interceptors on client
using
spring?

To test the service i wrote simple HelloClient:

public static void main(String[] args) {

                ApplicationContext context = new
ClassPathXmlApplicationContext("/clientAppContext.xml");
                HelloWorld client = (HelloWorld)
context.getBean("client");
                System.out.println("Invoking service...");
                String text = client.sayHi("Domagoj");
                System.out.println("Response=: " + text);
        }

This is my clientAppContext.xml:

<bean id="client" class="demo.spring.HelloWorld" 
factory-bean="clientFactory" factory-method="create"/>

        <bean id="clientFactory"
class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
          <property name="serviceClass" value="demo.spring.HelloWorld"/>
          <property name="address"
value="http://localhost:8080/SoaLab/HelloWorld"/>
          <property name="outInterceptors">
                        <list>
                                <bean
class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor"/>
                                <bean
class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
                                        <property name="properties">
                                                <map>
                                                        <entry
key="action" value="UsernameToken"/>
                                                        <entry
key="user" value="joe"/>
                                                        <entry
key="passwordType" value="PasswordText"/>
                                                        <entry
key="passwordCallbackClass"
value="demo.interceptors.ClientPasswordCallback"/>
                                                </map>
                                        </property>
                                </bean>
                        </list>
                </property>
        </bean>

The problem i have is that Response i receive from HelloWorld service is
null??
If i comment interceptors on both client and server side it all works
fine.

Any suggestions?

Thx in advance....


-- 
View this message in context:
http://www.nabble.com/WS-Security-and-CXF-tf4340880.html#a12365374
Sent from the cxf-user mailing list archive at Nabble.com.

----------------------------
IONA Technologies PLC (registered in Ireland)
Registered Number: 171387
Registered Address: The IONA Building, Shelbourne Road, Dublin 4, Ireland

Reply via email to