Axis2 multiple connection authentication issue - web-services

I have two servlets that access two corresponding Axis2 web services on the same host. One of the servlets is read-only, while the other writes to a database.
Each of the Axis2 web services uses BASIC authentication. The read-only web service uses a system account, while the write web service uses the user's credentials (which are submitted as part of a web form).
The problem I'm running into is that the servlet called second always fails authentication to its web service. For example, I can query the read-only service through it's servlet all I want, but I get a "401: Authorization Required" when I try to use the write service. If I call the write service first, I get the same error when I try to use the read-only service.
Here is how I am setting the credentials for the connections in the servlets:
Stub service = new Stub(serviceUrl);
HttpTransportProperties.Authenticator auth = new HttpTransportProperties.Authenticator();
auth.setUsername(username);
auth.setPassword(password);
auth.setPreemptiveAuthentication(true);
service._getServiceClient().getOptions().setProperty(HTTPConstants.AUTHENTICATE, auth);
The servlet that accesses the read-only service has this code in it's constructor. The servlet that accesses the write service has this code in it's doGet/doPost method.
It seems that the credentials for the first service called are getting cached somewhere, but I can't find where that could be. I saw a possible solution here, but I can't find where WSClientConstants.CACHED_HTTP_STATE is defined. The comments in this JIRA issue seems to imply that it's part of org.apache.axis2.transport.http.HTTPConstants but it's not there.
Specifics:
Axis version: 1.5.1
Tomcat Version: 6.0.26
Java version: 1.6.0_23

It turns out the connections to the two different services were using the same JSESSIONID. Thus, the connection to the second web service was trying to use a session authenticated for the first web service, causing the error.
My solution for this was to define an HttpClient for each service, done by the following
MultiThreadedHttpConnectionManager manager = new MuliThreadedHttpConnectionManager();
HttpClient client = new HttpClient(manager);
ConfigurationContext context = ConfigurationContextFactory.createDefaultConfigurationContext();
context.setProperty(HTTPConstants.CACHED_HTTP_CLIENT, client);
context.setProperty(HTTPConstants.REUSE_HTTP_CLIENT, true);
Stub service = new Stub(context, serviceUrl);
This allows both servlets to have a separate session for their corresponding services.

The important point is to create a dedicated ConfigurationContext.
I've solved in a simpler way using a default config context when creating the stub without the multithreaded connection factory
stub = new MyStub(ConfigurationContextFactory.createDefaultConfigurationContext(), myServicesUrl);

Related

TomEE server is not passing web service request to the webmethod

I am new in the area of SOAP Based web services. I am using TomEE server. The server is a bit customized according to my organization's need.
Few days back, when I was trying to run the web services example from TomEE website, I was able to generate the wsdl and calling the web service by a client.
Now, when I need to use the customized version of TomEE plus (by the organization), I can see that the request does reach to the server and hence there is a log entry also but my #WebMethod is not getting executed.
Does any one has any idea about any configuration which can prevent the request from reaching to the webservice method? Is there any pointer around how can I debug further to reach out to the root cause of this issue?
Without further information about what is customized it's like fishing in the dark.
I would guess that perhaps the global web.xml or the server.xml of tomee server is changed so that some URI context mappings are not forwarded or ignored. But it's only a lucky tip.

SoapUI: Create mock service with pass-through behavior for selected methods

While developing a web application I have the following use case:
a 3rd party Web Service with quite a lot of methods is deployed on a test server A (with a single endpoint, e.g. http://3rdPartyServer/3rdPartySvc?WSDL)
a new method is about to be implemented in the near future, but I need to use it now
the rest of the methods are used throughout my code extensively
So I would like to do the following:
Create a mock service in SoapUI locally, based on the new WSDL which includes the new WS method (i.e. a superset of the WS methods currently on server A)
point my local application server to use the SoapUI mock service endpoint
mock only the response of the new WS method (create a dummy response for it in SoapUI)
let the other WS method calls to reach server A and return whatever it returns normally (i.e. use SoapUI as a proxy for these calls)
I've gone through the SoapUI documentation regarding service mocking and have used it numerous times, but could not find an option for such "pass-through" behavior.
When you read in your WSDL, the endpoint will point to your server.
Open your service, and select the service endpoint.
Add a second endpoint, to point to your mock. SoapUI has little bit of documentation showing this here. Only step "2. Getting Started" applies, not step 3!
In each of your tests, where you are using the mocked method, you will need to select the mock endpoint. Further discussion is here.

Can a wcf client handle 2 version of a SOAP response from the same url?

I imported a service reference to a SOAP web service from the customer and coded my client based on that.
After going to production, they said they will launch a new version of the web service with changes to the output type of one of the requests I make to the service (among new messages that I don't consume).
I know I can update my service reference and update my client code to process the updated wsdl and launch an update to my client at the same time the web service updates.
But, is it possible to instrument the WCF code in some way so that I can handle both versions of the response without having to coordinate the update of my client with the update of the web service?
In most cases, NO. It depends on what has changes in the service interface? In most cases you'll need (and want) to upgrade your client. You can always ask them to support more versions of their interfaces.

WSO2 ESB how to securize a proxy by default when deploy

I have a lot of proxies in WSO2 ESB that I have to securize. I need them to be securized using Username Token when deploy, instead of browsing to the dashboard and enabling it one by one.
Any help?
I guess currently, you need to use management console and do it. From the UI, it is calling a backend web service. You can automate process by automating this backend web service. This web service is exposed by following component [1]. You can use soapui or some client program to automate this web service.
[1] http://svn.wso2.org/repos/wso2/carbon/platform/trunk/components/security/org.wso2.carbon.security.mgt/
I had similar requirement, here is how I solved it
Apply Role security to WSO2 ESB Proxy using Java API
Also you can find the test case here on how to use the methods
http://svn.wso2.org/repos/wso2/tags/carbon/3.2.3/products/bps/2.1.1/modules/integration/org.wso2.bps.management.test/src/test/java/org/wso2/bps/management/SecurityTest.java
Well here how the code snippet goes to secure any proxy service with default security scenarios of WSO2 ESB. In WSO2 ESB "scenario1" signifies Usernametoken based security. Now if you wish to secure your proxy with scenario1 follow the below code snippet:
public void applySecurityOnService(String serviceName, String policyId,
String[] userGroups, String[] trustedKeyStoreArray,
String privateStore)
throws SecurityAdminServiceSecurityConfigExceptionException,
RemoteException {
ApplySecurity applySecurity;
applySecurity = new ApplySecurity();
applySecurity.setServiceName(serviceName);
applySecurity.setPolicyId("scenario" + policyId); //scenario1 i.e. for Usernametoken security policyId should be 1
applySecurity.setTrustedStores(trustedKeyStoreArray);
applySecurity.setPrivateStore(privateStore);
applySecurity.setUserGroupNames(userGroups);
stub.applySecurity(applySecurity);
_logger.info("Security Applied Successfully");
}
Here is how you may call this method from your client class:
applySecurityOnService("MyProxy", "1", new String[]{"TestRole"}, new String[]{"wso2carbon.jks"}, "wso2carbon.jks");

Automatically pass a cookie with each web-service call

I have a standalone web-service client. When invoking any of the web-methods an additional "cookie" string must be implicitly(not as a web-method parameter) passed to the WS. The WS on the other end must be able to obtain the string and use it. How can this be achieved?
I invoke the service in the following way:
Service srv = Service.create(new URL(WSDL), QNAME);
myClassPort = srv.getPort(MyClass.class);
What I need is to put some code before the first line, which would make the client send this "cookie" string every time I invoke some remote method via myClassPort. Thx.
By default JAX-WS web services and clients are stateless. When a client makes a request, the server responds and sets a cookie on the connection, if it participates in a session. But, the JAX-WS client ignores that cookie and the server treats subsequent requests as new interaction. When the session is enabled, JAX-WS client sends the same cookie with each subsequent request so that server can keep track of the client session.
So you should not be using either cookies or HTTP sessions with web services. Return a token ID as part of the response; then the client can send that along with the next request.
Anyway:
JAX-WS web service clients must be configured to maintain session information (such as cookies), using the javax.xml.ws.session.maintain property.
Other web service stacks may have similar mechanisms.
On the Server Side
JAX-WS uses some handy annotations defined by Common Annotations for the Java Platform (JSR 250), to inject the web service context and declaring lifecycle methods.
WebServiceContext holds the context information pertaining to a request being served.
You don't need to implement javax.xml.rpc.server.ServiceLifecycle. With JAX-WS Web Service all you need to do is mark a field or method with #Resource. The type element MUST be either java.lang.Object or javax.xml.ws.WebServiceContext.
#WebService
public class HelloWorld {
#Resource
private WebServiceContext wsContext;
public void sayHello(){
MessageContext mc = wsContext.getMessageContext();
HttpSession session = ((javax.servlet.http.HttpServletRequest)mc.get(MessageContext.SERVLET_REQUEST)).getSession();
}
}
There are some misleading answers to this question, so I will attempt to highlight current best practices. Most of these suggestions are part of the OWASP security guidelines, which I strongly recommend anyone working on web development to review.
1) ALWAYS use temporary (session scoped) cookies.
2) All cookies should be protected and encrypted.
3) Do not pass tokens in request payloads
4) For any requests which return data that may be sent back to the server, include a nonce (single use token) in your responses.
5) later requests should (must) include the nonce and the cookie
Again, my recommendation is to review the OWASP guidelines and proceed accordingly.
You may want to look into using a service provider for authentication - this is much smarter than brewing your own solution as there are literally a million details that all must be correct. Auth0.com is one of these.