Basic Auth with WSS4J / camel cxf (Https) - java

For a SOAP web service, I have a working example of the configuration for PasswordDigest authentication via camel-cxf and WSS4J :
<camel-cxf:cxfEndpoint id="myService"
address="${ws.endpoint.address}"
serviceName="es:MyService"
wsdlURL="wsdl/myservice.wsdl"
endpointName="es:MyServicePort"
serviceClass="com.us.MyServiceEndpoint"
xmlns:es="http://us.com/services/MyService">
<camel-cxf:inInterceptors>
<bean class="org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JInInterceptor">
<property name="properties">
<map>
<entry key="action" value="UsernameToken"/>
<entry key="passwordType" value="PasswordDigest"/>
<entry key="passwordCallbackRef" value-ref="myPasswordCallback"/>
</map>
</property>
</bean>
</camel-cxf:inInterceptors>
</camel-cxf:cxfEndpoint>
We have a request to enable the same resource for BASIC authentication - how can this configuration be modified to do that?
I have changed the following line and tested via SOAP UI:
<entry key="passwordType" value="PasswordText"/>
However the result is a SOAP fault from UsernameTokenValidator.java:
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>These policy alternatives can not be satisfied:
{http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}
UsernameToken: Password hashing policy not enforced</faultstring>
</soap:Fault>
If anyone has some guidance here it would be appreciated.

You are mixing up the two different ways of configuring WS-Security in CXF.
The "PolicyBasedWSS4JInInterceptor" is used when you have a WS-SecurityPolicy to configure security. You don't need to actually add it at all, as CXF will automatically add it to the interceptor chain. It's configured via the configuration tags specified here: http://cxf.apache.org/docs/ws-securitypolicy.html. The configuration tags you are specifying as "properties" are ignored for the security policy case.
If you want to configure security via a policy in this case, you will need to remove the "HashPassword" policy if you want to support plaintext passwords.
If you want to only configure via "actions" you should be using the "WSS4JInInterceptor" instead (which the policy based interceptor extends).
Colm.

The WSS-PasswordType needed to change from PasswordText to PasswordDigest.

Related

What is the best option to set and get HTTP headers?? Using Apache CXF interceptor or a Filter

In one of my projects i have to set the ETag header in responses and read the if-none-matched header in the incoming requests. As of now i have implemented this using Apache CXF Filters however as i searched and found, the same functionality can be done by using interceptors as well. what are the significant advantages and/or disadvantages that i will have to experience if i proceed with CXF filters??
as of now i have implemented the filter and it works fine What would be the best practices in using a filter?
Here's a quote from http://cxf.apache.org/docs/jax-rs-filters.html.
Difference between JAXRS filters and CXF interceptors
JAXRS runtime flow is mainly implemented by a pair of 'classical' CXF interceptors. JAXRSInInterceptor is currently at Phase.UNMARSHAL (was at Phase.PRE_STREAM before CXF 2.2.2) phase while JAXRSOutInterceptor is currently at Phase.MARSHAL phase.
JAXRS filters can be thought of as additional handlers. JAXRSInInterceptor deals with a chain of Pre and Post Match ContainerRequestFilters, just before the invocation. JAXRSOutInterceptor deals with a chain of ContainerResponseFilters, just after the invocation but before message body writers get their chance.
Sometimes you may want to use CXF interceptors rather than writing JAXRS filters. For example, suppose you combine JAXWS and JAXRS and you need to log only inbound or outbound messages. You can reuse the existing CXF interceptors :
<beans>
<bean id="logInbound" class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
<bean id="logOutbound" class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
<jaxrs:server>
<jaxrs:inInterceptors>
<ref bean="logInbound"/>
</jaxrs:inInterceptors>
<jaxrs:outInterceptors>
<ref bean="logOutbound"/>
</jaxrs:outInterceptors>
</jaxrs:server>
<jaxws:endpoint>
<jaxws:inInterceptors>
<ref bean="logInbound"/>
</jaxws:inInterceptors>
<jaxws:outInterceptors>
<ref bean="logOutbound"/>
</jaxws:outInterceptors>
</jaxws:endpoint>
</beans>
Reusing other CXF interceptors/features such as GZIP handlers can be useful too.
At the moment it is not possible to override a response status code from a CXF interceptor running before JAXRSOutInterceptor, like CustomOutInterceptor above, which will be fixed.

How do I call a NTLM secured webservice using Camel-cxf?

In my Camel (2.13) flow, I want to call a webservice using Camel-CXF.
The webservice is secured using NTLM. I did find out thaat CXF itself supports NTLM, but I can't find anything on Camel-CXF. I did try the parameters username and password of course, but that didn't work.
Ik looks like Camel-CXF doesn't support it.
Any ideas on how to solve this?
I'm using java6 so i don't needs jcifs I think.
Roald
<cxf:cxfEndpoint id="sharepointQueryEndpoint"
address="http://yourhostwithpathtowsdl/_vti_bin/search.asmx"
serviceClass="com.somewhere.special.generated.QueryServiceSoap"
endpointName="ssp:SecureConnection"
xmlns:ssp="http://microsoft.com/webservices/OfficeServer/QueryService"
>
<cxf:properties>
<entry key="dataFormat" value="POJO"/>
<entry key="loggingFeatureEnabled" value="true" />
</cxf:properties>
<cxf:inInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
</cxf:inInterceptors>
<cxf:outInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
</cxf:outInterceptors>
</cxf:cxfEndpoint>
<http:conduit name="{http://microsoft.com/webservices/OfficeServer/QueryService}SecureConnection.http-conduit">
<http:client
AllowChunking="false"
MaxRetransmits="11"
Connection="Keep-Alive"
ReceiveTimeout="60000"
CacheControl="No-Cache"
/>
<http:authorization>
<sec:UserName>Domain\Username</sec:UserName>
<sec:Password>Password</sec:Password>
<sec:Authorization>NTLM</sec:Authorization>
</http:authorization>
</http:conduit>
The attribute serviceClass in the cxfEndpoint configuration is point to the Interface which is generated by wsdl2java.enter code here
Note: When this condfiguration is run from a Windows based machine it is not working. During the handshake it will substitute the configured username/password in the http-conduit with the credentials of the user currently logged in.
See Can Java's 'single sign-on' (use credentials from 'Credential Manager') on Windows be disabled? for more information

Sign and Encrypt SOAP Messages with Apache CXF

I'm trying to write a "Secure Hello World" web service using Apache CXF also; I should note that I'm kind of new to Java and WS-* stuff.
Basically, what I want to do is a hello-world web service with soap messages to and from this web service signed and encrypted using x.509 certificate(s).
I have already read the tutorial on Apache CXF site about WS-Security but; I want to use WS-SecurityPolicy instead of Interceptors.
Can anyone point me in the right direction?
Here's a blog with details on using Apache CXF: Adding X.509 security headers to Apache CXF SOAP calls (WS-SecurityPolicy method)
There's also a tutorial with source code configured for using the WS-SecurityPolicy Method.
EDIT: fixed broken link, added link to tutorial.
There is now a good overview of the various settings for WS-SecurityPolicy on the CXF site, and it references the link above.
In a nutshell (in case the links are blown away again), the WS-SecurityPolicy is configured similar to the CXF interceptor method described on the CXF wiki except for a few changes in the cxf.xml and the cxf-servlet.xml:
cxf.xml
<jaxws:client name="{http://myport" createdFromAPI="true">
<!-- You will need to add the corresponding values to a properties file -->
<jaxws:properties>
<entry key="ws-security.callback-handler" value="client.ClientKeystorePasswordCallback"/>
<entry key="ws-security.encryption.properties" value=keystore.properties"/>
<entry key="ws-security.signature.properties" value="keystore.properties"/>
<entry key="ws-security.encryption.username" value="myservicekey"/>
</jaxws:properties>
cxf-servlet.xml
<jaxws:properties>
<entry key="ws-security.callback-handler">
<ref bean="myPasswordCallback"/>
</entry>
<entry key="ws-security.encryption.properties" value="serviceKeystore.properties"/>
<entry key="ws-security.signature.properties" value="serviceKeystore.properties"/>
<entry key="ws-security.encryption.username" value="useReqSigCert"/>
</jaxws:properties>
Since web services work over HTTP, you can secure them by using the HTTPS protocol.
Here is a resource that can help point you in the right direction: Using JAX-WS-Based Web Services with SSL
While this resource is for JAX-WS, you should find that a lot of it will carry over to Apache CXF.
Cheers.

Does Spring 3.0 provides a service definition file?

I'm wondering about Spring 3.0 whether it provides an automatically generated service definition page after I defined services.
With SOAP we have a WSDL file which contains WHAT, HOW and WHERE we can call a service.
Is that possible with Spring 3.0 or not?
Yes it does. Just add "?WSDL" to the URL of your Spring-generated web service and you'll get the definition. Also you can append "?xsd=1" instead and you'll get the schema you need (this is referenced also from the WSDL).
You can use an MBeanExporter to expose all of your services via JMX, which would be viewable through a JMX dashboard on your container (IE Tomcat, Jboss, etc). This is an easy way to account for 'what is deployed'. Your question is not entirely clear what sort of artifact you're looking for though.
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="autodetect" value="true"/>
</bean>
Will automatically export all of your defined beans as MBeans. Usually that's not entirely what you want, so alternatively, you'll specify them manually.
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="beans">
<map>
<entry key="bean:name=testBean1" value-ref="testBean"/>
</map>
</property>
</bean>
I agree with Chochos.
These[?wsdl, ?xsd=N] are universal standard to find the service definition file and any Datacontract defined in the wsdl.
example:
if http://localhost:8080/MyService is your service endpoint then it is service container's responsibility to make the WSDl available at http://localhost:8080/MyService,
by default.
The answer is Yes,
Use tag in your message dispatcher spring context file.
if your message dispatcher bean id is spring-ws then the spring context file for it would be spring-ws-servlet.xml.
In that context file,
import the namespace http://www.springframework.org/schema/web-services/web-services-2.0.xsd
xmlns:sws="http://www.springframework.org/schema/web-services".
then use the tag dynamic-wsdl from this namespace.
Also, you can set attributes for it like portType, binding and id. This will generate the wsdl file for you. You can view it by querying for it in the browser
/.wsdl

validating wsdl/schema using cxf

I am having a hard time getting cxf to validate an xml request that my service creates for a 3rd party.
My project uses maven. Here is my project structure
Main Module :
+ Sub-Module1 = Application
+ sub-Module2 = Interfaces
In Interfaces, inside src/main/resources I have my wsdl and xsd.
so, src/main/resources
+ mywsdl.wsdl.
+ myschema.xsd
The interface submodule is listed as a dependency in the Application-sub-module.
inside Application sub-module, there is a cxsf file in src/maim/resources.
<jaxws:client name="{myTargerNameSpaceName}port"
createdFromAPI="true">
<jaxws:properties>
<entry key="schema-validation-enabled" value="true" />
</jaxws:properties>
</jaxws:client>
AND:.
<jaxws:endpoint name="{myTargetNameSpaceName}port"
wsdlLocation="/mywsdl.wsdl"
createdFromAPI="true">
<jaxws:properties>
<entry key="schema-validation-enabled" value="true" />
</jaxws:properties>
</jaxws:endpoint>
I tried changing the "name="{myTargetNameSpaceName}port" to "name="{myEndPointName}port"
But to no anvil.
My application works. But it just do not validate the xml I am producing that has to be consumed by a 3rd party application.
I would like to get the validation working, so that any request that I send would be a valid one.
Any suggestions?
Just add #org.apache.cxf.annotations.SchemaValidation annotation on your service implementation class and schema validation will work.
First ensure that the value of the name attribute is {NAMESPACE}PORT_NAME where NAMESPACE is your namespace URI and PORT_NAME is the name of your WSDL port. Without seeing your WSDL, I don't know if you named your WSDL port "port" or if you are just giving a sanitized example.
For example, my WSDL namespace is "http://example.com/services" and the name of my WSDL port element is "myPort", the Spring configuration would look like this
<jaxws:endpoint name="{http://example.com/services}myPort" >
...
See "CreatedFromAPI" attribute description in CXF docs
If that doesn't solve your problem, try looking at the wsdl_first example code, upgrading your CXF version, and/or posting your question with test code demonstrating your issue to the CXF user list.
We had similar issues. CXF 2.3.1 fixed the issue for us on incoming messages but not outgoing messages.
https://issues.apache.org/jira/browse/CXF-3233
We work around it by marshaling the messages and validating them within the server before sending them out through the CXF interceptor chain. We validate using org.springframework.xml.validation.XmlValidator.
I'm hoping a future version of CXF will solve this but this is what we do for now.

Categories

Resources