WS02 API Manager malformed request to endpoint URL - wso2

We have our API being managed by WS02 API manager, but there seems to be some issue with the way it constructs the outgoing request into the configured endpoint URL. We see this sort of error from our endpoint when we make a request to the API manager:
Cannot bind to address "http://<HOST>:<PORT>http://<HOST>:<PORT>/<RESOURCE>
The URL is clearly incorrect as it is prepending the host part of the URL twice. We've put a debugging proxy in between the API manager and our endpoint and it shows the outgoing request looks like this:
GET http://<HOST>:<PORT>/<RESOURCE> HTTP/1.1
...
Host: <HOST>:<PORT>
It isn't normal for the host to be included in the first line; that should come from the "Host" header. But as it is, it makes sense we are getting the above error. Note, when we proxy this through something like Nginx, it works fine, but the server we are actually using for our endpoint doesn't like it. I'm guessing Nginx has been written in such a way so that it can resolve this kind of (technically incorrect) request.

We are adding propery 'POST_TO_URI' to our synapse API configuration in order to make the outgoing URL a complete URL [1]. This is useful when sending the messages through a proxy server. You can remove that property by modifying your API in AM_HOME/repository/deployment/server/synapse-configs/default/api/ directory. Remove the below property in your relevant APIs which sending requests to such backend servers.
<property name="POST_TO_URI" value="true" scope="axis2"/>
[1]https://docs.wso2.org/display/ESB460/HTTP+Transport+Properties

Related

Hostname/IP does not match certificate's altnames

I'm working on a REST API that itself makes requests to another REST API -- basically, it provides a more convenient interface and also some extra functionality. Let's call my REST API X and the REST API to which my API calls Y.
Whenever I make requests to the endpoints of Y on my machine with cURL, REST Client, etc; all requests are successful. Like I mentioned, my API X is acting as a wrapper to Y, so when I upload my API to aws Lambda and create the respective endpoints in API Gateway, when I make a request to one of the endpoints I get this message:
Hostname/IP does not match certificate's altnames: Host:
X.execute-api.us-west-2.amazonaws.com. is not in the cert's altnames:
DNS:somehostname.com
So far, I have uploaded two lambdas with their respective endpoints, and the problem above only seems to be happening for one of the endpoints (the request to the other endpoint happens without problem).
I would like to know why this is happening and if this is a problem on my side? Meaning, is there something I am forgetting or something I can do -- except bypassing some security mechanism -- to fix this on my side? Whenever I make requests to the original API Y on my machine I'm not getting any errors so I'm a bit puzzled by this.
I think you're missing how SSL certificates work. Depending on how the certificate is setup for "API Y" you can't just connect to a different server and have it work. While you are conceptually a proxy to the real back end from the client perspective, you're a totally different host and the SSL certificate is for "API Y" only.
This is the same reason that you can't decide that you want to have an API named trustme.google.com - you don't have control over the google.com domain (presumably).
If there is a way to change the hostname that your client connections are using (to something like proxy.yourdomain.tld) then you can setup an SSL certificate for that domain and things should work. However, at that point you may run into CORS issues - post again if you have that issue.
AWS documents how to setup your own SSL certificate for API gateway. It's pretty easy though if you have an existing certificate you may need to use the AWS certificate manager to get a (free) certificate for your API.
Update 03/10/2022: Before your proxy hands off the request to the real backend service, make sure to set Host header to the hostname of the real service, see here.
I also developed a HTTP client -> APIG endpoint -> Lambda -> Host application, where the Lambda acts as a proxy between the client and the 3rd party Host. My Lambda is written in Node.js. I was getting this same exact error when the Lambda tried to invoke the 3rd party Host,
{
"statusCode": 500,
"body": "Hostname/IP does not match certificate's altnames: Host: zyxfghsk.execute-api.us-east-1.amazonaws.com. is not in the cert's altnames: DNS:*.somehost.com, DNS:somehost.com"
}
My setup uses Lambda Proxy integration with APIG, and I pass the set of HTTP headers from the client as-is to the 3rd party Host. I noticed the headers contained header Host: zyxfghsk.execute-api.us-east-1.amazonaws.com, which I think comes from the client. So in the Lambda code, right before passing the request to the 3rd party Host, I just simply delete the Host header from the request, and the problem went away. Another approach I was trying earlier, which also works, but not as ideal is that I was setting NODE_TLS_REJECT_UNAUTHORIZED=0 in the Node.js environment, which effectively disables SSL certificate validation by Node.js.
I believe, though not 100% certain, that in my case at least the error was getting thrown by Node.js certificate validation.
Update 03/10/2022: Before your proxy hands off the request to the real backend service, make sure to set Host header to the hostname of the real service, see here.

SOAP request through JMeter with authentication

I'm having trouble sending a JMeter SOAP request through HTTP Request element -
Through SOAPUI I'm sending the request with the following properties:
Authentication via SOAP
But I cannot receive a valid response when I try to add these username password. I've tried to place it in HTTP Header Manager/ in HTTP Authorization Manager, but with no luck. I receive either error:
Response code: 404 Response message: Not Found
when placing this in the HTTP Authorization Manager and
HTTP Error 400. The request has an invalid header name
when placing the username and password in the header manager (with wss password type field, while in HTTP Authorization Manager there is not option like this).
What can I do to have a valid response from the server like I get in SOAPUI?
If you need to replicate SoapUI request I would suggest just to record the request from the SoapUI via JMeter HTTP(S) Test Script Recorder
In JMeter
File -> Template -> Recording -> Create
Workbench -> HTTP(S) Test Script Recorder -> Start
In SoapUI
File -> Preferences -> Proxy Settings
Host: localhost, Port: 8888
Enable proxy in SoapUI
Execute your request
Expand Thread Group -> Recording Controller in JMeter and observe the recorded request.
You may also need to correlate timestamps using __time() function check out Take the Pain out of Load Testing Secure Web Services for details on bypassing different web services security in JMeter tests.

Custom Uri or endpoint on WSO2

We have just installed our WSO2 ESB, and we are trying to create some proxies services with customs endpoints.
The default endoint format is:
http://{host}:{port}/services/{Proxy Service Name}
I'd like to have something like:
http://{host}:{port}/services/utilities/{Proxy Service Name}
http://{host}:{port}/services/public/{Proxy Service Name}
I followed this tutorial:
http://wso2.org/library/knowledge-base/2011/01/custom-urls-wso2-esb-proxy-services
but we have a problem, when I send a request to my custom endpoint, I have no answer.
suggestions?
I assume that you were able to properly create a custom endpoint and "I have no answer" means you didn't get any response. If it is the case following are the possible reasons for that,
Proxy service endpoint didn't receive the request
Proxy service didn't configured properly to response back
So test whether the 1 is the reason you can simply put a log mediator with following configuration in inSequence,
<log level="full"/>
then if the proxy service received a message it will log it in console. If that works could you please post your proxy service configuration to check whether it is properly defined.
Well, it seems that we've found a solution, I'm going to resume the full solution.
As the tutorial indicates, to costumize your proxy service endpoint, you have to add the following handler on the axis2.xml configuration:
<handler name="CustomURIBasedDispatcher" class="org.apache.synapse.core.axis2.CustomURIBasedDispatcher"/>
Then, you can customize your endpoint on the design view or on the source view, I've choosen the source view, adding this parameter:
<parameter name="ServiceURI">/services/intern</parameter>
The custom endpoint is autogenerated as:
http://{host}:{port}/services/intern.myWebservice
But I has not worked for me. If I send a request to the custom endpoint, I have no response.
I've solved the problem, adding to the "ServiceURI" parameter the name of the service:
<parameter name="ServiceURI">/services/intern/myWebService</parameter>
then you have to send the request to the following endpoint:
http://{host}:{port}/services/intern/myWebService
So now you have a custom endpoint for every proxy service.
Thanks Malith for your help.

WSO2 ESB providing HTTP 202 response on Proxy Service

I am trying to setup very simple WSO2 ESB Proxy service. While using it, I am getting HTTP 202 response back and WSO2 ESB is not doing anything with the request beside logging it. Here is the background of my setup
My service implementation is using SOAP 1.2 over Http 1.1. When my client opens the connection to the server, it fires first request and asks for keep-alive connection. The ESB passes the request to the actual implementation and sends response back with transfer-encoding as chunked. So far it works as desired.
After the initial request response exchange, my client submits several requests in parallel and I get HTTP 202 responses for all of them. Looking at logs, it seems ESB is not sending the request to the actual implementation ever.
Is there something that I am doing wrong? How do I fix it?
What happens in this scenario is that your subsequent requests are hitting the main sequence of the WSO2 ESB. That is why you can only see a log for those requests. As you have already narrowed down this happens due to the jsessionId attached to the URL. To overcome this issue you can create a REST API with URL pattern to match the correct URL path. Please refer the following documentation.
https://docs.wso2.com/display/ESB481/Creating+APIs

SOAP request logging Tomcat 7 Axis2

We are trying to log all http requests made to our Tomcat server, in particular SOAP requests.
Our server setup is as follows:
Tomcat 7.0.11
Axis 2
Gentoo Linux
So far we have used the RequestDumperFilter class however this only shows us the header information.
What we require is the ability to view the request body containing the SOAP request XML.
I guess you could make use of some request processing components but I'm not sure if there is an easy way to view the request body in Tomcat.
From what I know, the ExtendedAccessLogValve provides the most information about the request but even this is missing the body.
The most simple solution would be to move the logging away from Tomcat and use a proxy server. You place the proxy between the server and it's clients and do the logging in the proxy.
Proxy receives request, logs it, then forwards to Tomcat which generates response, sends it to the proxy which logs it and then sends it to client. The simplest proxy I used (and did its job pretty well) was the Apache TCP Monitor.
Additionally you could look at something like Fiddler and see if that helps.