2

When my client AngularJS app tried to reach some REST API exposed via WSO2 API Manager (v2.0.0), I get this response (IP, port replaced with "am_host" and "am_port") :

Refused to set unsafe header "Origin" XMLHttpRequest cannot load http://am_host:am_port/ReferentielInfoConso/offres-tarifaires/identifiants. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access. 

I can confirm "Access-Control-Allow-Origin" header is not present in the response to the "OPTIONS" request when I check the headers in Chrome developper tool.

header_chrome

When I request the same URL with same HTTP method (GET /ReferentielInfoConso/offres-tarifaires/identifiants HTTP/1.1) in Chrome Advanced REST Client, I can see the expected header "Access-Control-Allow-Origin" and I can get access to the resource :

capture_rest_client

So what should I do to make it work in my AngularJS App (without creating a Node.js backend, I need to keep it very light) ? Why enabling CORS in WSO2 is not enough ?

EDIT : If my AngularJS app requests the API directly to the Tomcat 7 endpoint (CORS enabled by default) without going through WSO2 AM, it works perfectly.

EDIT 2 : When my AngularJS App tries to reach the WSO2 API without sending the authorization token, I get a 401 response including the expected "Access-Control-Allow-Origin" header. As soon as I add the token, it looks like it follows a different route through WSO2 AM and I don't get the "Access-Control-Allow-Origin" header.

EDIT 3 : if I had an "Autorization" header and try to reach my Tomcat 7 backend directly, I get a "cross-origin" problem too but I guess it's because "Authorization" header is not in the list of headers allowed in Tomcat conf. It is in the list of headers allowed by WSO2 AM though (I've added both "authorization" and "Authorization" to be sure it will work).

6
  • We had CORS issues too and this is what we had to do. For all the APIs we were accessing we had to go to the configurarions {APIHOME}\repository\deployment\server\synapse-configs\default\api and find the specific file. We had to add the handler below. I do not remember if our symptoms were exactly what you were describing but wanted to put it out there to you just incase. <handler class="org.wso2.carbon.apimgt.gateway.handlers.security.CORSRequestHandler"> <property name="apiImplementationType" value="INLINE"/> </handler> Commented Sep 29, 2016 at 16:38
  • @Tristan Did you define OPTIONS method for the corresponding resource of the API? If yes, please provide wire logs. lakshanigamage.blogspot.com/2015/03/… Commented Sep 29, 2016 at 16:39
  • @jchaplin : ok I'll try this. Commented Sep 29, 2016 at 17:16
  • @Bhathiya When u enable CORS config in wso2 v2.0.0, "OPTIONS" is in the "Access Control Allow Methods" list, and I have not removed it. Is that what u mean ? Commented Sep 29, 2016 at 17:18
  • @Bhathiya When I activate the logging as requested, I can see in the response to the "OPTIONS" request : "Allow: HEAD, DELETE, POST, PATCH, PUT, GET[\r][\n]", but this does not correspond to the list in my UI parameters nor to my conf/api-manager.xml file : "<Access-Control-Allow-Methods>GET,PUT,POST,DELETE,PATCH,OPTIONS</Access-Control-Allow-Methods>". Commented Sep 29, 2016 at 17:36

4 Answers 4

2

If you don't have OPTIONS method defined in resources list of API Publisher UI, APIM should send all CORS headers, as specified in api-manager.xml.

Please also note you can define CORS configuration per API from publisher UI. If you have that configured, the CORS configuration given in api-manager.xml is ignored for that particular API.

If your backend is CORS-enabled, you can send OPTIONS requests to backend too. For that, you can create a resource in API Publisher for /* OPTIONS.

Sign up to request clarification or add additional context in comments.

6 Comments

Ok, so you are telling me WSO2 doesn't work as expected right ? so where should I submit a bug report ?
You can report issues at wso2.org/jira/browse/APIMANAGER. Please make sure you attach a screenshot of your API resource list in publisher UI.
I may be related to this bug : wso2.org/jira/browse/APIMANAGER-5361 cause I'm using the default version to access API as you can see in the URL I'm calling.
ah, yes that should be the reason. I missed the fact that you were using default endpoint. So, the endpoints with version work fine for you?
Yes it works, but it's not fine I can't use the default version mechanism because of this bug. See my final answer below.
|
2

So here is the final answer : There are multiple bugs in WSO2 who don't make it easy to enable CORS to interact with APIs directly from a web app (no backend).

First of all, for no documented reason, the /token API is not affected by the global api conf in repository/conf/api-manager.xml, so you need to go deep in the conf (repository/deployment/server/synapse-configs/default/api/TokenAPI.xml) and add the CORSRequestHandler conf copying it from any other xml file in the same directory.

Secondly, when u use the default version URL (http://host:port/Context/myapi instead of http://host:port/Context/1.0/myapi when the 1.0 version is marked as default version), you won't receive the CORS headers : https://wso2.org/jira/browse/APIMANAGER-5361

So after manually configuring CORShandler in TokenAPI.xml and replacing my calls with explicit version calls, I could remove my reverse-proxy. I'm still expecting the default version bug to be corrected cause default version is a useful feature.

Comments

1

I solved the bug by modifying the file default_api_template.xml contained in the folder repository\resources\api_templates of WSO2 API Manager distribution.

I just modified the line

<resource methods="POST PATCH GET DELETE HEAD PUT"> 

by adding OPTIONS verb in this way:

<resource methods="POST PATCH GET DELETE HEAD PUT OPTIONS">* 

Now also the default endpoint works with cors calls.

Comments

0

For my particular situation, where I want client apps to request a token and call APIs in AJAX, I've chosen the simplest solution : configuring an Apache web server on the same machine as WSO2 with these simple conf lines below.

 Header set Access-Control-Allow-Origin "*" Header set Access-Control-Allow-Methods "GET,PUT,POST,DELETE,PATCH,OPTIONS" Header set Access-Control-Allow-Headers "authorization,Access-Control-Allow-Origin,Content-Type,SOAPAction,Authorization" ProxyPass "/" "http://10.22.106.101:8280/" ProxyPassReverse "/" "http://10.22.106.101:8280/" 

1 Comment

see final answer below

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.