WebService Certificate Validation using WebSphere, Spring-WS and WSS4J - web-services

i'm working on a webapp offering SOAP WebServices using Spring-WS 2.0. The WebService Requests need to be signed with a certificate which is of course validated on the server. In order to do this WSS4J and a truststore is used - here the spring-config:
<bean class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
<property name="validationActions" value="Signature" />
<property name="validationSignatureCrypto">
<bean class="org.springframework.ws.soap.security.wss4j.support.CryptoFactoryBean">
<property name="keyStorePassword" value="pass"/>
<property name="keyStoreLocation" value="location"/>
</bean>
</property>
</bean>
The application should be deployed to WebSphere 7 and the major requirement is, that the truststore should not be shipped with the application but be provided by the Application Server.
Does anybody know how i can achieve, that WebSphere either provides the truststore or how WebSphere can be configured to perform the security authorization ? The major challenge seems to be, that Spring-WS is used instead of using the WebSphere's facility for WebServices...

I don't work with Spring-WS so don't know the details of it.
WAS has a truststore which is where the list of trusted signer certificates are stored.
THe keystores and truststores can kept # multiple levels if you desire (e.g node,cell etc).
For detailed info you can look at a publicly available PPT
http://www.websphereusergroup.org.uk/wug/files/presentations/25/25_3_WAS61SecUpdate.pdf.
I don't know the version of WAS that you are using WAS 6.1 and WAS 7.x are the most widely used ones these days!
HTH
Manglu

Related

Any potential security risk when exposing ActiveMQ web console in AWS?

I was unable to access the ActiveMQ web console in 5.16 version.
I opened the required ports in AWS security group and I checked which ports are configured for console and the broker URL, yet the browser said "Page Not Found" so I looked into the jetty.xml and noticed this line:
<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
<!-- the default port number for the web console -->
<property name="host" value="127.0.0.1"/>
<property name="port" value="8161"/>
</bean>
I changed the host to 0.0.0.0:
<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
<!-- the default port number for the web console -->
<property name="host" value="0.0.0.0"/>
<property name="port" value="8161"/>
</bean>
Now I am able to access the web console. However does this give any security risk?
There is always inherently more risk when exposing additional points of entry into a system (e.g. a management console).
The ActiveMQ web console is a powerful tool which can be used to delete messages, remove destinations, stop the broker, etc. If a user gains unauthorized access to the web console then they can make a real mess. If you expose the web console to external users then be sure to secure it according to the documentation.

How to Call External WebService using Proxy Host form JBOSS EAP 7.0.0

We have couple of external third party web services to send business data. But the constrain is that, those services need to be called from dedicated server (say 120.10.20.123 ).
Now any external service call need to be re directed through proxy server (120.10.20.123).
Can somebody please help me to understand how to achieve this functionality using JBOSS EAP 7.0.0
Thanks in advance.
Ajoy
You have to modify in
standalone.xml
at
the following:
<system-properties>
<property name="http.proxyHost" value="yourProxyIpAddress"/>
<property name="http.proxyPort" value="yourProxyPort"/>
<property name="http.nonProxyHosts" value="localhost"/>
</system-properties>
You can also do it programmatically but it's not related to question.
Or you could put a webserver to redirect the call to leave jboss clean.

Spring WS digest authentication with nonce, create challenge

I am relatively new to SOAP web services, and it seems to be a basic thing, but still, I cannot find the way so solve it. I have a SOAP server written using Spring WS with XWS security. These are the relevant beans:
<bean id="wsSecurityInterceptor" class="org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor">
<property name="policyConfiguration"
value="classpath:security-policy.xml"/>
<property name="callbackHandlers">
<list>
<ref bean="passwordValidationHandler"/>
</list>
</property>
</bean>
<bean id="passwordValidationHandler" class="org.springframework.ws.soap.security.xwss.callback.SimplePasswordValidationCallbackHandler">
<property name="users">
<props>
<prop key="user">*****</prop>
</props>
</property>
</bean>
And the following is security-policy.xml:
<xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
<xwss:RequireUsernameToken passwordDigestRequired="true" nonceRequired="true"/>
<xwss:UsernameToken digestPassword="true" useNonce="true"/>
</xwss:SecurityConfiguration>
The thing is that I want to extablish a digest authentication using nonce (a one-time token that prevents an intercepted request from being sent again). As far as I know (and it is described here http://www.whitemesa.com/soapauth.html#S4), the server should create a challenge (nonce and timestamp, I think) and then the client should encrypt it with its password and timestamp and send it back to the server for verification. And this it should work for every request. Even if the user sends an empty request, the server should provide a challenge. But in my case it does not work. Am I missing something?
As it turned up, it is not necessarily the server who should generate nonce. I generated it on client, concatenated and hashed it according to the rules and then sent to the server. Frankly speaking, I could only find the root of error by debugging Spring WS sources and looking for where exactly an authentication problem is.

Configuring an HTTP proxy in a Spring web app

I have been searching around for a proper way to configure an HTTP proxy in a Spring web application. Unfortunately, each time the results I get are about AOP proxies and not HTTP proxies.
Basically, one module of my application is running a webservice client configure in the Spring XML file with JAX-WS, giving something like :
<bean id="heartBeatWebservice" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
<property name="serviceInterface" value="the.web.service.interface"/>
<property name="wsdlDocumentUrl" value="http://thehost:theport/theservicename.wsdl"/>
<property name="serviceName" value="TheServiceName"/>
<property name="namespaceUri" value="http://the.namespace/"/>
<property name="portName" value="TheWebServicePortName"/>
</bean>
But my app has to run behind an HTTP proxy for being able to call the web service, and I must acknowledge that I don't know how to do it properly within the Spring context.
I tried in some main class that I wrote to try out this code at first :
System.setProperty("http.proxyHost", "my.proxy.addr");
System.setProperty("http.proxyPort", "8080");
Unfortunately, it didn't work as expected. I assume there is a nice way to configure an HTTP proxy in a Spring context but can't find out how ...
Can you give me a hint ?
There isn't any Spring-specific HTTP proxy configuration required.
It should use the standard Java HTTP proxy settings, so you're going along the right lines.
Can you try running the main class using -Dhttp.proxyHost=my.proxy.host -Dhttp.proxyPort=8080 rather than using System.setProperty?

Accessing a password-protected WSDL in Weblogic when calling a web service

We're using Spring and JAXWS-generated client classes to access web services in a weblogic-deployed app. The WSDL defining the web service is remote and password-protected (basic http authentication). In a unit test it suffices to define a proxy in ~/.metro folder with the url and http password to use when accessing it. Is there a similar trick for Weblogic in some configuration file? Or is there some other common way of solvind this issue?
According to the documentation (Chapter 6. Using Spring Web Services on the Client):
6.2.1.1.1. HTTP transports
There are two implementations of the
WebServiceMessageSender interface for
sending messages via HTTP. The default
implementation is the
HttpUrlConnectionMessageSender, which
uses the facilities provided by Java
itself. The alternative is the
CommonsHttpMessageSender, which uses
the Jakarta Commons HttpClient. Use
the latter if you need more advanced
and easy-to-use functionality (such as
authentication, HTTP connection
pooling, and so forth).
(...)
The folowing example shows how
override the default configuration,
and to use Commons Http to
authenticate using HTTP
authentication:
<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<constructor-arg ref="messageFactory"/>
<property name="messageSender">
<bean class="org.springframework.ws.transport.http.CommonsHttpMessageSender">
<property name="credentials">
<bean class="org.apache.commons.httpclient.UsernamePasswordCredentials">
<constructor-arg value="john"/>
<constructor-arg value="secret"/>
</bean>
</property>
</bean>
</property>
<property name="defaultUri" value="http://example.com/WebService"/>
</bean>
Did you try this?
Update: Since you're using a JAX-WS client (which is not what I understood from "we're using Spring"), you can either:
Set a default Authenticator as described in HTTP basic authentication with JAX-WS (Client).
Use Spring and configure a http-conf:authorization for the conduit element. See Client HTTP Transport (including SSL support).
You can provide your own Authenticator. That way it will work if the WDSL itself is protected by basic HTTP authentication.
#WebServiceRef(wsdlLocation = "https://laka/sito?wsdl")
static XxxService service;
public static void main(String[] args) {
Authenticator.setDefault(new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("user", "password".toCharArray());
}
});
service = new XxxService();
Xxx port = service.getXxxPort();
// invoke webservice and print response
XxxResponse resp = port.foo();
System.out.println(resp.toString());
}