The endpoint reference (EPR) for the Operation not found is - wsdl

I have been struggling with the following error the last couple of
days can you please help!
I generated my server and client code using the wsdl2java tool from a
wsdl 2.0 file.
When invoking the webservice I am getting the following error:
org.apache.axis2.AxisFault: The endpoint reference (EPR) for the
Operation not found is
/axis2/services/MyService/authentication/?username=Denise345&password=xxxxx
and the WSA Action = null
My service is displayed on the axis2 webpage with all available methods.
Here is the output from TcpMon
==============
Listen Port: 8090
Target Host: 127.0.0.1
Target Port: 8080
==== Request ====
GET /axis2/services/MyService/authentication/?username=Denise345&password=xxxxx
HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
SOAPAction: ""
User-Agent: Axis2
Host: 127.0.0.1:8090
==== Response ====
HTTP/1.1 500 Internal Server Error
Server: Apache-Coyote/1.1
Content-Type: application/xml;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 12 May 2011 15:53:20 GMT
Connection: close
12b
<soapenv:Reason xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Text xml:lang="en-US">The endpoint reference (EPR) for the
Operation not found is
/axis2/services/MyService/authentication/?username=Denise345&password=xxxxx
and the WSA Action = null</soapenv:Text></soapenv:Reason>
0
==============
I am using:
axis2-1.5.4
Tomcat 7.0.8
wsdl 2.0 file
Please help!

In my case it was caused by a wrong Content-Type in the HTTP POST. Setting it to text/xml solved the problem.

Try adding ?wsdl to the string.

As described by Eran Chinthaka at http://wso2.com/library/176/
If Axis2 engine cannot find a service and an operation for a message,
it immediately fails, sending a fault to the sender. If service not
found - "Service Not found EPR is " If
service found but not an operation- "Operation Not found EPR is and WSA Action = "
In your case the service is found but the operation not. The Axis2 engine uses SOAPAction in order to figure out the requested operation and, in your example, the SOAPAction is missing, therefore I would try to define the SOAPAction header

It happens because the source WSDL in each operation has not defined the SOAPAction value.
e.g.
<soap12:operation soapAction="" style="document"/>
His is important for axis server.
If you have created the service on netbeans or another, don't forget to set the value action on the tag #WebMethod
e.g. #WebMethod(action = "hello", operationName = "hello")
This will create the SOAPAction value by itself.

Action is null means that no Action in given SOAP Message (Request XML). You must set Action before SOAP call:
java.net.URL endpoint = new URL("<URL>"); //sets URL
MimeHeaders headers = message.getMimeHeaders(); // getting MIME Header
headers.addHeader("SOAPAction", "<SOAP Action>"); //add Action To Header
SOAPMessage response = soapConnection.call(<SOAPMessage>, endpoint); //then Call
soapConnection.close(); // then Close the connection

I had this same problem using curl to send a soap request. Solved it by adding "content-type: text/xml" to the http header.
I hope this helps someone.

This error is coming because while calling the service, it is not getting the WSDL file of your service.
Just check whether WSDL file of your service is there--> run server and from browser run axis 2 apps on local host and check the deployed services and click on your service, then it shows WSDL file of your service.....or check the service path in your client file.
I hope it may help you to resolve the problem.

This can be solved by disabling validation
<proxy>
<!-- . . . -->
<parameter name="disableOperationValidation">true</parameter>
</proxy>

Late answer but:
I see you do a GET - should be a POST ?

try removing the extra '/' after the operation name (authentication) when invoking through the client
/axis2/services/MyService/authentication?username=Denise345&password=xxxxx

It seems don't find wsdl file..
I've solved adding wsdlLocation parameter at javax.jws.WebService annotation

By removing cache wsdl-* files in /tmp folder, my problem was solved
see https://www.drupal.org/node/1132926#comment-6283348
be careful about permission to delete
I'm in ubuntu os

On Websphere Application Server, in the same situation, it helped deleting the Temp folders while the server was stopped.
I ran into the situation when the package of the service changed.

Open WSDL file and find:
<soap:operation soapAction="[actionNameIsHere]" style="document"/>
Add to the requests header [request send to service]:
'soapAction' : '[actionNameIsHere]'
This work for me.
For devs. using node-soap [ https://github.com/vpulim/node-soap ] - example:
var soap = require('soap');
var options = {
...your options...
forceSoap12Headers: true
}
soap.createClient(
wsdl, options,
function(err, client) {
if(err) {
return callBack(err, result);
}
client.addHttpHeader('soapAction', '[actionNameIsHere]');
...your code - request send...
});

I got this error because the SOAP request I was sending to the server was malformed and had an empty Body
In this case the error message from the server is misleading and can be solved changing the request content, without changing anything about operations, URLs, WSDL, etc

Related

FastAPI RedirectResponse gets {"message": "Forbidden"} when redirecting to a different route

Please bare with me for a question for which it's nearly impossible to create a reproducible example.
I have an API setup with FastAPI using Docker, Serverless and deployed on AWS API Gateway. All routes discussed are protected with an api-key that is passed into the header (x-api-key).
I'm trying to accomplish a simple redirect from one route to another using fastapi.responses.RedirectResponse. The redirect works perfectly fine locally (though, this is without api-key), and both routes work perfectly fine when deployed on AWS and connected to directly, but something is blocking the redirect from route one (abc/item) to route two (xyz/item) when I deploy to AWS. I'm not sure what could be the issue, because the logs in CloudWatch aren't giving me much to work with.
To illustrate my issue let's say we have route abc/item that looks like this:
#router.get("/abc/item")
async def get_item(item_id: int, request: Request, db: Session = Depends(get_db)):
if False:
redirect_url = f"/xyz/item?item_id={item_id}"
logging.info(f"Redirecting to {redirect_url}")
return RedirectResponse(redirect_url, headers=request.headers)
else:
execution = db.execute(text(items_query))
return convert_to_json(execution)
So, we check if some value is True/False and if it's False we redirect from abc/item to xyz/item using RedirectResponse(). We pass the redirect_url, which is just the xyz/item route including query parameters and we pass request.headers (as suggested here and here), because I figured we need to pass along the x-api-key to the new route. In the second route we again try a query in a different table (other_items) and return some value.
I have also tried passing status_code=status.HTTP_303_SEE_OTHER and status_code=status.HTTP_307_TEMPORARY_REDIRECT to RedirectResponse() as suggested by some tangentially related questions I found on StackOverflow and the FastAPI discussions, but that didn't help either.
#router.get("/xyz/item")
async def get_item(item_id: int, db: Session = Depends(get_db)):
execution = db.execute(text(other_items_query))
return convert_to_json(execution)
Like I said, when deployed I can successfully connect directly to both abc/item and get a return value if True and I can also connect to xyz/item directly and get a correct value from that, but when I pass a value to abc/item that is False (and thus it should redirect) I get {"message": "Forbidden"}.
In case it can be of any help, I try debugging this using a "curl" tool, and the headers I get returned give the following info:
Content-Type: application/json
Content-Length: 23
Connection: keep-alive
Date: Wed, 27 Jul 2022 08:43:06 GMT
x-amzn-RequestId: XXXXXXXXXXXXXXXXXXXX
x-amzn-ErrorType: ForbiddenException
x-amz-apigw-id: XXXXXXXXXXXXXXXX
X-Cache: Error from cloudfront
Via: 1.1 XXXXXXXXXXXXXXXXXXXXXXXXX.cloudfront.net (CloudFront)
X-Amz-Cf-Pop: XXXXX
X-Amz-Cf-Id: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
So, this is hinting at a CloudFront error. Unfortunately I don't see anything slightly hinting at this API when I look into my CloudFront dashboard on AWS, there literally is nothing there (I do have permissions to view the contents though...)
The API logs in CloudWatch look like this:
2022-07-27T03:43:06.495-05:00 Redirecting to /xyz/item?item_id=1234...
2022-07-27T03:43:06.495-05:00 [INFO] 2022-07-27T08:43:06.495Z Redirecting to /xyz/item?item_id=1234...
2022-07-27T03:43:06.496-05:00 2022-07-27 08:43:06,496 INFO sqlalchemy.engine.Engine ROLLBACK
2022-07-27T03:43:06.496-05:00 [INFO] 2022-07-27T08:43:06.496Z ROLLBACK
2022-07-27T03:43:06.499-05:00 END RequestId: 6f449762-6a60189e4314
2022-07-27T03:43:06.499-05:00 REPORT RequestId: 6f449762-6a60189e4314 Duration: 85.62 ms Billed Duration: 86 ms Memory Size: 256 MB Max Memory Used: 204 MB
I have been wondering if my issue could be related to something I need to add to somewhere in my serverless.yml, perhaps in the functions: part. That currently looks like this for these two routes:
events:
- http:
path: abc/item
method: get
cors: true
private: true
request:
parameters:
querystrings:
item_id: true
- http:
path: xyz/item
method: get
cors: true
private: true
request:
parameters:
querystrings:
item_id: true
Finally, it's probably good to note that I have added custom middleware to FastAPI to handle the two different database connections I need for connecting to other_items and items tables, though I'm not sure how relevant this is, considering this functions fine when redirecting locally. For this I implemented the solution found here. This custom middleware is the reason for the redirect in the first place (we change connection URI based on route with that middleware), so I figured it's good to share this bit of info as well.
Thanks!
As noted here and here, it is mpossible to redirect to a page with custom headers set. A redirection in the HTTP protocol doesn't support adding any headers to the target location. It is basically just a header in itself and only allows for a URL (a redirect response though could also include body content, if needed—see this answer). When you add the authorization header to the RedirectResponse, you only send that header back to the client.
A suggested here, you could use the set-cookie HTTP response header:
The Set-Cookie HTTP response header is used to send a cookie from the
server to the user agent (client), so that the user agent can send it back to
the server later.
In FastAPI—documentation can be found here and here—this can be done as follows:
from fastapi import Request
from fastapi.responses import RedirectResponse
#app.get("/abc/item")
def get_item(request: Request):
redirect_url = request.url_for('your_endpoints_function_name') #e.g., 'get_item'
response = RedirectResponse(redirect_url)
response.set_cookie(key="fakesession", value="fake-cookie-session-value", httponly=True)
return response
Inside the other endpoint, where you are redirecting the user to, you can extract that cookie to authenticate the user. The cookie can be found in request.cookies—which should return, for example, {'fakesession': 'fake-cookie-session-value-MANUAL'}—and you retrieve it using request.cookies.get('fakesession').
On a different note, request.url_for() function accepts only path parameters, not query parameters (such as item_id in your /abc/item and /xyz/item endpoints). Thus, you can either create the URL in the way you already do, or use the CustomURLProcessor suggested here, here and here, which allows you to pass both path and query parameters.
If the redirection takes place from one domain to another (e.g., from abc.com to xyz.com), please have a look at this answer.

Getting JSESSIONID from JIRA using RestAssured throwing unknown host error

I have written a script using RestAssured to connect to Jira and get Session ID. Below is my code.
public void getJIRACookieTest(){
System.setProperty("https.proxyHost", "Host");
System.setProperty("https.proxyPort", "PortNo");
System.setProperty("https.proxyUserName","UserName");
System.setProperty("https.proxyPassword","Password");
Response res = given().header("Content-Type","application/json").
when().
body("{\"username\":\"test\",\"password\":\"test\"}").
post("https://jira_url/rest/auth/1/session").
then().extract().response();
System.out.println(res.prettyPrint().toString());
}
Here am getting unknow host error message.
Then i tried Postman and its perfectly working fine. I just selected no authentication, Content-Type as applicatio/json and body with user details
{\"username\":\"test\",\"password\":\"test\"}
in postman.
Not sure why am getting unknown host when i try with RestAssured.
Your help is really appreciated.
Thanks,
Narendra
From your comments I gather that you are connecting w/o a proxy using Postman and this works.
You are setting an HTTPS proxy in your RestAssured test anyway:
System.setProperty("https.proxyHost", "Host");
System.setProperty("https.proxyPort", "PortNo");
System.setProperty("https.proxyUserName","UserName");
System.setProperty("https.proxyPassword","Password");
You should be fine after removing these lines from your test.

Grails CORS not enabled because no origin

I have a grails 2.2.4 application. I wanted to enable CORS
So I installed cors plugin by having the following line in build config.
plugins {
runtime ':cors:1.1.8'
}
Then in the config.groovy
cors.headers = ['Access-Control-Allow-Origin': '*']
But after this when I run the application, CORS in not enabled. So I debugged the CORS plugin. The issue seems to be in CorsFilter class in the following method
private boolean checkOrigin(HttpServletRequest req, HttpServletResponse resp) {
String origin = req.getHeader("Origin");
if (origin == null) {
//no origin; per W3C spec, terminate further processing for both preflight and actual requests
return false;
}
The origin parameter in the above line is always null as the request does not have the parameter 'Origin'. Is there something i'm doing wrong? I'm not looking for the answer which says add a manual header with the name "Origin" since that is not exactly a proper fix
I'm quite new to CORS so appriciate the help.
In addition to Access-Control-Allow-Origin, and in addition to setting the Origin header on request, you probably need to specify these response headers as well:
Access-Control-Allow-Headers: accept
Access-Control-Allow-Headers: origin
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Method: GET
Access-Control-Allow-Method: POST
Also make sure you respond to HTTP OPTIONS requests with these headers and a blank 200 OK response.
For now, let's assume that RestClient is sending the Origin header properly. It may still be getting stripped by your application. You can prevent this using the Access-Control-Allow-Headers: Origin header.
Most of the problems I have had with my web services is that the right headers are being sent, but they are stripped from the message by my web server. So I tend to adopt a shotgun approach of "allow everything" and then one by one remove what I don't need. My allow-headers header usually is pretty long and I end up having to include stuff like Content-Type, X-Requested-With and other junk before my requests will finally go through.
I further recommend that you test using something besides RestClient, if only as a sanity check. I use Postman, a free Chrome app, for all my messaging tests. It looks to me like the problem is with RestClient not sending the proper Origin header.

Liferay Webservice JSON response type

I have a web service in liferay.. and the response would be
{"response":{"status":{"code":"200","message":"ok"},"userProfile": {"screenName":"testUser","userName":"testUser"}}}
I'm getting following error when consuming it from an ios client:
Encountered unexpected response with status code: 200 (MIME Type: text/javascript)
The MIME type must be application/json for json resonse; please change
Where to configure in Liferay to make the MIME type to be "application:json"
Thanks for your help!
I think it needs to be configured in your ios client rather than in Liferay.
Since Liferay is sending the response as desired and the error you are getting is on the client side.
Hope this helps.
Create a servlet ..
from the doGet method
set response.setContentType("application/json");
then add this servlet in the web.xml
response mime type would be "application/json"

ServiceAuthorizationManager exception always sending xml response

I have a custom ServiceAuthorizationManager implemented in wcf webhttp service to do api key verification. It sends a webfaultexception with the code 403 if the key is invalid.
But the issue is, when the exception is thrown, it s always send to the client as xml.
The service accepts both JSON and XML and it s working fine for all the other operations except for the exception from the manager.
No matter if I set the accept header or content type the result is always xml. But for other requests, the response type switches perfectly according to the content-type header
Here's the web.config
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" />
Any help is really appriciated.
If anyone else ran into this issue: looks like no way to fix it. The solution I did was to do the verification in the service's constructor. Make sure the instance context mode is set to per call.
More info http://amilagm.com/2012/04/better-way-to-do-api-key-verification-in-wcf-webhttp-services/

Resources