|
View:
New views
8 Messages
—
Rating Filter:
Alert me
|
|
|
UsernameToken Authentication with WSS4JI am facing a problem with the password comparison using WSS4J interceptors. I see the username and password are passed from the client to the server correctly and invoking PasswordCallbackHandler from SOAP message logs. As per my understanding the actual password comparison is done by WSS4J. The problem I am facing is that the service is getting invoked even if the passwords are not matching while I am expecting the SOAP fault to be thrown. The client is sending the password "test" while the server is expecting "test123" for the user "admin". Here are my logs and configuration. Please let me know if I am missing anything.
Server side applicationContext-cxf.xml: <jaxws:endpoint id="helloWorld" implementor="com.mydomain.cxfauth.HelloWorldImpl" address="/HelloWorld"> <jaxws:features> <bean class="org.apache.cxf.feature.LoggingFeature" /> </jaxws:features> <jaxws:inInterceptors> <bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" /> <ref bean="wss4jInConfiguration" /> </jaxws:inInterceptors> </jaxws:endpoint> <bean id="wss4jInConfiguration" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor"> <property name="properties"> <map> <entry key="action" value="UsernameToken" /> <entry key="passwordType" value="PasswordText" /> <entry> <key> <value>passwordCallbackRef</value> </key> <ref bean="passwordCallback" /> </entry> </map> </property> </bean> <bean id="passwordCallback" class="com.mydomain.cxfauth.interceptors.PasswordCallbackHandler"/> Server side Password callback handler: public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; logger.debug("identifier on server: " + pc.getIdentifer()); if (pc.getIdentifer().equals("admin")) { logger.debug("Inside if: " + pc.getIdentifer()); //set the password on the callback. This will later be compared to the password which was sent from the client. pc.setPassword("test123"); } } Client side client-cxf.xml: <bean id="client" class="com.mydomain.cxfauth.HelloWorld" factory-bean="clientFactory" factory-method="create" /> <bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean"> <property name="serviceClass" value="com.mydomain.cxfauth.HelloWorld" /> <property name="address" value="http://localhost:8080/cxfauth/services/HelloWorld" /> <property name="outInterceptors"> <list> <bean class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" /> <ref bean="wss4jOutConfiguration" /> </list> </property> </bean> <bean id="wss4jOutConfiguration" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor"> <property name="properties"> <map> <entry key="action" value="UsernameToken" /> <entry key="user" value="admin" /> <entry key="passwordType" value="PasswordText" /> <entry> <key> <value>passwordCallbackRef</value> </key> <ref bean="passwordCallback" /> </entry> </map> </property> </bean> <bean id="passwordCallback" class="com.mydomain.cxfauthclient.interceptors.PasswordCallbackHandler" /> Client side PasswordCallbackHandler: public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; logger.debug("identifier on client: " + pc.getIdentifer()); if (pc.getIdentifer().equals("admin")) { //set the password on the callback on client side pc.setPassword("test"); } } Server Log: Sep 12, 2007 10:25:21 AM org.apache.cxf.transport.servlet.CXFServlet replaceDestionFactory INFO: servlet transport factory already registered Sep 12, 2007 10:26:10 AM org.apache.cxf.interceptor.LoggingInInterceptor handleMessage INFO: Inbound Message -------------------------------------- <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Header> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soap:mustUnderstand="1"><wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-12741398" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><wsse:Username xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">admin</wsse:Username><wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">test</wsse:Password></wsse:UsernameToken></wsse:Security></soap:Header><soap:Body><ns1:sayHi xmlns:ns1="http://cxfauthmydomaincom/"><arg0>Durgaprasad</arg0></ns1:sayHi></soap:Body></soap:Envelope> -------------------------------------- 2007-09-12 10:26:10,728 - DEBUG (com.mydomain.cxfauth.interceptors.PasswordCallbackHandler:handle:20) - identifier on server: admin 2007-09-12 10:26:10,744 - DEBUG (com.mydomain.cxfauth.interceptors.PasswordCallbackHandler:handle:22) - Inside if: admin Sep 12, 2007 10:26:11 AM org.apache.cxf.interceptor.LoggingOutInterceptor$LoggingCallback onClose INFO: Outbound Message -------------------------------------- <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns1:sayHiResponse xmlns:ns1="http://cxfauth.mydomain.com/"><return>Welcome, Durgaprasad to the CXF web services</return></ns1:sayHiResponse></soap:Body></soap:Envelope> -------------------------------------- Client response Log: Sep 12, 2007 10:26:09 AM org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromClass INFO: Creating Service {http://cxfauth.mydomain.com/}HelloWorldService from class com.mydomain.cxfauth.HelloWorld 2007-09-12 10:26:10,135 - DEBUG (com.mydomain.cxfauthclient.interceptors.PasswordCallbackHandler:handle:20) - identifier on client: admin 2007-09-12 10:26:11,119 - DEBUG (com.mydomain.cxfauthclient.CXFAuthClient:main:21) - Response: Welcome, Durgaprasad to the CXF web services |
|
|
Re: UsernameToken Authentication with WSS4JYou'll need a ValidateUserTokenInterceptor as shown here:
http://arsenalist.com/2007/07/31/cxf-ws-security-using-jsr-181-interceptor-annotations-xfire-migration/
|
|
|
Re: UsernameToken Authentication with WSS4JHi Zarar,
Thanks for the link. I have changed my configurations with the @InInterceptors in the service implementation class and also coded WSSecurityInterceptor and ValidateUserTokenInterceptor as shown in the blog. Still I am getting the following exception when I try to invoke the service. Any clues are appreciated. 2007-09-12 16:37:43,562 - DEBUG (com.mydomain.cxfauth.interceptors.WSSecurityInterceptor:handleMessage:25) - Inside handleMessage() of WSSecurityInterceptor. Sep 12, 2007 4:37:43 PM org.apache.cxf.phase.PhaseInterceptorChain doIntercept INFO: Interceptor has thrown exception, unwinding now org.apache.cxf.binding.soap.SoapFault: NO_SAAJ_DOC at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:116) at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:59) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:207) at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:73) at org.apache.cxf.transport.servlet.ServletDestination.doMessage(ServletDestination.java:78) at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:231) at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:139) at org.apache.cxf.transport.servlet.CXFServlet.invoke(CXFServlet.java:271) at org.apache.cxf.transport.servlet.CXFServlet.doPost(CXFServlet.java:249) at javax.servlet.http.HttpServlet.service(HttpServlet.java:709) .... Further, I want to know where the passwords comparison occurs. From the following code snippet of ValidateUserTokenInterceptor: if (!principal.isPasswordDigest() || principal.getNonce() == null || principal.getPassword() == null || principal.getCreatedTime() == null) { throw new RuntimeException("Invalid Security Header"); } else { //Where does the passwords compared?? userTokenValidated = true; } Thanks, Durga
|
|
|
Re: UsernameToken Authentication with WSS4JYou're probably not adding SAAJInInterceptor() to your interceptor chain.
|
|
|
Re: UsernameToken Authentication with WSS4JYou're probably not adding SAAJInInterceptor() to your interceptor chain.
|
|
|
Re: UsernameToken Authentication with WSS4JHi Zarar,
Thanks for the reply. I have added SAAJInInterceptor() to the interceptor chain and error has gone. But the problem is that the service is getting invoked eventhough the passwords are not matching. I want to understand where does the password comparison occurs. From logs I have the following: - Inside ValidateUserTokenInterceptor.. - principal.isPasswordDigest()= false - principal.getNonce()= null - principal.getPassword()= test - principal.getCreatedTime()= null The client is sending the password "test" while the CallbackHandler that is registered with the server is setting the password "test123". Thanks, Durga
|
|
|
Re: UsernameToken Authentication with WSS4JThe password comparison happens I believe in the UsernameToken class. Why don't you do a check like
String passwordDigest = UsernameToken.doPasswordDigest(principal.getNonce(), principal.getCreatedTime(), "REAL PASSWORD"); if (!principal.getPassword().equals(passwordDigest)) { throw new RuntimeException("Invalid credentials"); } or just the following if there's no digest being used: if (!principal.getPassword().equals("REAL PASSWORD")) { throw new RuntimeException("Invalid credentials"); }
|
|
|
RE: UsernameToken Authentication with WSS4JHi,
The problem lies in WSS4J's processing of the password. If the incoming password is hashed, then the CallbackHandler is used to retrieve a password, which is then compared in the UsernameTokenProcessor. However, if the password is in plaintext, as yours is, then all validation is delegated to the CallbackHandler implementation. See the javadoc here for further explanation: http://ws.apache.org/wss4j/apidocs/org/apache/ws/security/processor/User nameTokenProcessor.html#handleUsernameToken(org.w3c.dom.Element,%20javax .security.auth.callback.CallbackHandler) A JIRA has already been raised in WSS4J to improve the processing of password: http://issues.apache.org/jira/browse/WSS-54 Colm. -----Original Message----- From: gdprao [mailto:gdprao@...] Sent: 13 September 2007 01:59 To: cxf-user@... Subject: Re: UsernameToken Authentication with WSS4J Hi Zarar, Thanks for the reply. I have added SAAJInInterceptor() to the interceptor chain and error has gone. But the problem is that the service is getting invoked eventhough the passwords are not matching. I want to understand where does the password comparison occurs. From logs I have the following: - Inside ValidateUserTokenInterceptor.. - principal.isPasswordDigest()= false - principal.getNonce()= null - principal.getPassword()= test - principal.getCreatedTime()= null The client is sending the password "test" while the CallbackHandler that is registered with the server is setting the password "test123". Thanks, Durga Zarar Siddiqi wrote: > > You're probably not adding SAAJInInterceptor() to your interceptor chain. > > > > gdprao wrote: >> >> Hi Zarar, >> >> Thanks for the link. I have changed my configurations with the >> @InInterceptors in the service implementation class and also coded >> WSSecurityInterceptor and ValidateUserTokenInterceptor as shown in >> blog. Still I am getting the following exception when I try to invoke >> the service. Any clues are appreciated. >> >> 2007-09-12 16:37:43,562 - DEBUG >> (com.mydomain.cxfauth.interceptors.WSSecurityInterceptor:handleMessage:2 5) >> - Inside handleMessage() of WSSecurityInterceptor. >> Sep 12, 2007 4:37:43 PM org.apache.cxf.phase.PhaseInterceptorChain >> doIntercept >> INFO: Interceptor has thrown exception, unwinding now >> org.apache.cxf.binding.soap.SoapFault: NO_SAAJ_DOC >> at >> org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JI nInterceptor.java:116) >> at >> org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JI nInterceptor.java:59) >> at >> org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorC hain.java:207) >> at >> org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiati onObserver.java:73) >> at >> org.apache.cxf.transport.servlet.ServletDestination.doMessage(ServletDes tination.java:78) >> at >> org.apache.cxf.transport.servlet.ServletController.invokeDestination(Ser vletController.java:231) >> at >> org.apache.cxf.transport.servlet.ServletController.invoke(ServletControl ler.java:139) >> at >> org.apache.cxf.transport.servlet.CXFServlet.invoke(CXFServlet.java:271) >> at >> org.apache.cxf.transport.servlet.CXFServlet.doPost(CXFServlet.java:249) >> at javax.servlet.http.HttpServlet.service(HttpServlet.java:709) >> .... >> >> Further, I want to know where the passwords comparison occurs. From the >> following code snippet of ValidateUserTokenInterceptor: >> >> if (!principal.isPasswordDigest() || >> principal.getNonce() == null || >> principal.getPassword() == null || >> principal.getCreatedTime() == null) { >> throw new RuntimeException("Invalid Security >> Header"); >> } else { >> >> //Where does the passwords compared?? >> >> userTokenValidated = true; >> } >> >> >> Thanks, >> Durga >> >> >> >> >> Zarar Siddiqi wrote: >>> >>> You'll need a ValidateUserTokenInterceptor as shown here: >>> >>> or-annotations-xfire-migration/ >>> >>> >>> >>> >>> >>> >>> gdprao wrote: >>>> >>>> I am facing a problem with the password comparison using WSS4J >>>> interceptors. I see the username and password are passed from the >>>> client to the server correctly and invoking PasswordCallbackHandler >>>> from SOAP message logs. As per my understanding the actual >>>> comparison is done by WSS4J. The problem I am facing is that the >>>> service is getting invoked even if the passwords are not matching while >>>> I am expecting the SOAP fault to be thrown. The client is sending the >>>> password "test" while the server is expecting "test123" for the user >>>> "admin". Here are my logs and configuration. Please let me know if I >>>> am missing anything. >>>> >>>> Server side applicationContext-cxf.xml: >>>> >>>> <jaxws:endpoint id="helloWorld" >>>> implementor="com.mydomain.cxfauth.HelloWorldImpl" >>>> address="/HelloWorld"> >>>> >>>> <jaxws:features> >>>> <bean >>>> </jaxws:features> >>>> <jaxws:inInterceptors> >>>> <bean >>>> class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" /> >>>> <ref bean="wss4jInConfiguration" /> >>>> </jaxws:inInterceptors> >>>> </jaxws:endpoint> >>>> <bean id="wss4jInConfiguration" >>>> class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor"> >>>> <property name="properties"> >>>> <map> >>>> <entry key="action" value="UsernameToken" /> >>>> <entry key="passwordType" value="PasswordText" /> >>>> <entry> >>>> <key> >>>> <value>passwordCallbackRef</value> >>>> </key> >>>> <ref bean="passwordCallback" /> >>>> </entry> >>>> </map> >>>> </property> >>>> </bean> >>>> >>>> <bean id="passwordCallback" >>>> class="com.mydomain.cxfauth.interceptors.PasswordCallbackHandler"/> >>>> >>>> Server side Password callback handler: >>>> >>>> public void handle(Callback[] callbacks) throws IOException, >>>> UnsupportedCallbackException { >>>> WSPasswordCallback pc = (WSPasswordCallback) >>>> logger.debug("identifier on server: " + pc.getIdentifer()); >>>> if (pc.getIdentifer().equals("admin")) { >>>> logger.debug("Inside if: " + pc.getIdentifer()); >>>> //set the password on the callback. This will later be compared to >>>> the password which was sent from the client. >>>> pc.setPassword("test123"); >>>> } >>>> >>>> } >>>> >>>> Client side client-cxf.xml: >>>> >>>> <bean id="client" class="com.mydomain.cxfauth.HelloWorld" >>>> factory-bean="clientFactory" factory-method="create" /> >>>> >>>> <bean id="clientFactory" >>>> class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean"> >>>> <property name="serviceClass" >>>> value="com.mydomain.cxfauth.HelloWorld" /> >>>> <property name="address" >>>> >>>> <property name="outInterceptors"> >>>> <list> >>>> <bean >>>> class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" /> >>>> <ref bean="wss4jOutConfiguration" /> >>>> </list> >>>> </property> >>>> </bean> >>>> <bean id="wss4jOutConfiguration" >>>> class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor"> >>>> <property name="properties"> >>>> <map> >>>> <entry key="action" value="UsernameToken" /> >>>> <entry key="user" value="admin" /> >>>> <entry key="passwordType" value="PasswordText" /> >>>> <entry> >>>> <key> >>>> <value>passwordCallbackRef</value> >>>> </key> >>>> <ref bean="passwordCallback" /> >>>> </entry> >>>> </map> >>>> </property> >>>> </bean> >>>> <bean id="passwordCallback" >>>> >>>> class="com.mydomain.cxfauthclient.interceptors.PasswordCallbackHandler" >>>> /> >>>> >>>> Client side PasswordCallbackHandler: >>>> >>>> public void handle(Callback[] callbacks) throws IOException, >>>> UnsupportedCallbackException { >>>> WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; >>>> logger.debug("identifier on client: " + pc.getIdentifer()); >>>> if (pc.getIdentifer().equals("admin")) { >>>> //set the password on the callback on client side >>>> pc.setPassword("test"); >>>> } >>>> >>>> } >>>> >>>> >>>> Server Log: >>>> >>>> Sep 12, 2007 10:25:21 AM org.apache.cxf.transport.servlet.CXFServlet >>>> replaceDestionFactory >>>> INFO: servlet transport factory already registered >>>> Sep 12, 2007 10:26:10 AM >>>> org.apache.cxf.interceptor.LoggingInInterceptor handleMessage >>>> INFO: Inbound Message >>>> -------------------------------------- >>>> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> >>>> <soap:Header> >>>> <wsse:Security >>>> xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wsse curity-secext-1.0.xsd" >>>> soap:mustUnderstand="1"><wsse:UsernameToken >>>> xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssec urity-utility-1.0.xsd" >>>> wsu:Id="UsernameToken-12741398" >>>> xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wsse curity-secext-1.0.xsd"><wsse:Username >>>> xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wsse curity-secext-1.0.xsd">admin</wsse:Username><wsse:Password >>>> Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-t oken-profile-1.0#PasswordText" >>>> xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wsse curity-secext-1.0.xsd">test</wsse:Password></wsse:UsernameToken></wsse:S ecurity></soap:Header><soap:Body><ns1:sayHi >>>> xmlns:ns1="http://cxfauthmydomaincom/"><arg0>Durgaprasad</arg0></ns1:say Hi></soap:Body></soap:Envelope> >>>> -------------------------------------- >>>> 2007-09-12 10:26:10,728 - DEBUG >>>> (com.mydomain.cxfauth.interceptors.PasswordCallbackHandler:handle:20) - >>>> identifier on server: admin >>>> 2007-09-12 10:26:10,744 - DEBUG >>>> (com.mydomain.cxfauth.interceptors.PasswordCallbackHandler:handle:22) - >>>> Inside if: admin >>>> Sep 12, 2007 10:26:11 AM >>>> org.apache.cxf.interceptor.LoggingOutInterceptor$LoggingCallback >>>> onClose >>>> INFO: Outbound Message >>>> -------------------------------------- >>>> <soap:Envelope >>>> xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns1:s ayHiResponse >>>> xmlns:ns1="http://cxfauth.mydomain.com/"><return>Welcome, Durgaprasad >>>> to the CXF web >>>> services</return></ns1:sayHiResponse></soap:Body></soap:Envelope> >>>> -------------------------------------- >>>> >>>> Client response Log: >>>> >>>> Sep 12, 2007 10:26:09 AM >>>> org.apache.cxf.service.factory.ReflectionServiceFactoryBean >>>> buildServiceFromClass >>>> INFO: Creating Service >>>> from class com.mydomain.cxfauth.HelloWorld >>>> 2007-09-12 10:26:10,135 - DEBUG >>>> (com.mydomain.cxfauthclient.interceptors.PasswordCallbackHandler:handle: 20) >>>> - identifier on client: admin >>>> 2007-09-12 10:26:11,119 - DEBUG >>>> (com.mydomain.cxfauthclient.CXFAuthClient:main:21) - Response: Welcome, >>>> Durgaprasad to the CXF web services >>>> >>>> >>>> >>>> >>> >>> >> >> > > -- View this message in context: http://www.nabble.com/UsernameToken-Authentication-with-WSS4J-tf4431064. html#a12646893 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 |
| Free embeddable forum powered by Nabble | Forum Help |