Angular JS, Jetty CORS issue - angularjs

I've been ripping my hair out over this issue. Im attempting to enable CORS between an Angular App and a Jersey Server. Basically I've implemented a filter for jersey that should allow angular access to the server:
public class SimpleCORSFilter implements ContainerResponseFilter {
/**
* Add the cross domain data to the output if needed
*
* #param creq The container request (input)
* #param cres The container request (output)
* #return The output request with cross domain if needed
*/
#Override
public ContainerResponse filter(ContainerRequest creq, ContainerResponse cres) {
cres.getHttpHeaders().add("Access-Control-Allow-Origin", "*");
cres.getHttpHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
cres.getHttpHeaders().add("Access-Control-Allow-Credentials", "true");
cres.getHttpHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
cres.getHttpHeaders().add("Access-Control-Max-Age", "1209600");
return cres;
}
}
I've then added this as an init param to my web.xml.
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
<param-value>com.complaints.security.SimpleCORSFilter</param-value>
</init-param>
When I hit the URL - mysite:8080/ComplaintService/service/user/authenticate from postman with a post containing user details it returns fine (as is expected from postman) and the header contains all the correct CORS related headers. When I try to make the call from angular for some reason none of the CORS headers are being returned and it fails. Even if I just hit the URL from the browser as a GET the CORS headers are being returned. This is my angular call:
$http.post('http://mysite:8080/ComplaintService/service/user/authenticate', user).then(function(data) {
alert(JSON.stringify(data));
});
Basically I'm just wondering am I missing something simple? Or perhaps could it be related to the spring security filter? I was thinking the application could potentially be blocked from reaching the jersey filter. Here's the spring filter:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Angular is currently deployed on jersey - mysite:8081 and the server is deployed on mysite:8080. Any help would be greatly appreciated!

I overcame this issue using a library - com.thetransactioncompany:cors-filter:1.3.2 and adding some config to my web.xml.
<filter>
<filter-name>CORS</filter-name>
<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
<init-param>
<param-name>cors.allowOrigin</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.supportedHeaders</param-name>
<param-value>origin, content-type, accept</param-value>
</init-param>
<init-param>
<param-name>cors.allowGenericHttpRequests</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.supportedMethods</param-name>
<param-value>GET, POST, HEAD, PUT, DELETE</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CORS</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
I think the issue was because the spring security filter was being called first, this seemed to resolve the issue.

Related

No response when making REST request is tested on rest client in Apache Camel

No response when making REST request is tested on rest client in Apache Camel
I am newbie and working with Apache Camel and RESTful services. When I make request with url, I am getting
CamelHttpTransportServlet - No consumer to service request org.apache.catalina.connector.RequestFacade
This is my some content of web.xml
<servlet>
<display-name>Camel Http Transport Servlet</display-name>
<servlet-name>myServlet</servlet-name>
<servlet-class>org.apache.camel.component.servlet.CamelHttpTransportServlet</servlet-class>
<load-on-startup>0</load-on-startup>
<init-param>
<param-name>ignoreDuplicateServletName</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>myServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
This is the code for my RouteBuilder
public void configure() throws Exception {
restConfiguration().component("servlet").contextPath("/my").bindingMode(RestBindingMode.off).endpointProperty("servletName", "myServlet");
rest("/card").post("/load")
.type(CardActRequest.class)
.to("direct:load");
onException(Exception.class)
.handled(true)
.bean(CardRequestResponse, "createErrorResponse");
from("direct:load")
.process(CardRequestResponse)
.bean(CardRequestResponse, "processRequest")
.choice()
.when(simple("${body} != null"))
.to("stream:out")
.bean(CardRequestResponse, "processResponse").endChoice()
.otherwise()
.bean(CardRequestResponse, "createErrorResponse");
}
Now when I make the request in following order:
http://localhost:8080/my/card/load

Prerender io java wrong route

I am having a problem with prerender.io. It works just fine if I am using node/express on localhost, but when I am trying to make it work with java (https://github.com/greengerong/prerender-java/) on google app engine it re-routes automatically.
When I write this into my browser and hit enter,
http://www.example.com/?_escaped_fragment_=/browse/761238167868/
It redirects automatically to
http://www.example.com/?_escaped_fragment_=/browse/761238167868#!/browse
In app.js I have the following:
module.config(['$routeProvider','$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider.when('/browse', {
templateUrl: 'views/browse.html'
//a lot of .when() ....
}).otherwise({redirectTo: '/browse'});
I believe it is a problem with the app engine server or the middleware installation, because it works just fine with node/express.
Do I need to rewrite something to make app engine handle hashbangs (#!) or something?
Here's my web.xml:
<filter>
<filter-name>prerender</filter-name>
<filter-class>com.github.greengerong.PreRenderSEOFilter</filter-class>
<init-param>
<param-name>crawlerUserAgents</param-name>
<param-value>FacebookExternalHit</param-value>
</init-param>
<init-param>
<param-name>crawlerUserAgents</param-name>
<param-value>facebookexternalhit</param-value>
</init-param>
<init-param>
<param-name>crawlerUserAgents</param-name>
<param-value>facebookexternalhit/1.0</param-value>
</init-param>
<init-param>
<param-name>crawlerUserAgents</param-name>
<param-value>facebookexternalhit/1.1</param-value>
</init-param>
<init-param>
<param-name>crawlerUserAgents</param-name>
<param-value>Facebot</param-value>
</init-param>
<init-param>
<param-name>prerenderToken</param-name>
<param-value>mytoken</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>prerender</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

Confused about how to handle CORS OPTIONS preflight requests

I'm new to working with Cross Origin Resource Sharing and trying to get my webapp to respond to CORS requests. My webapp is a Spring 3.2 app running on Tomcat 7.0.42.
In my webapp's web.xml, I have enabled the Tomcat CORS filter:
<!-- Enable CORS (cross origin resource sharing) -->
<!-- http://tomcat.apache.org/tomcat-7.0-doc/config/filter.html#CORS_Filter -->
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
My client (written with AngularJS 1.2.12) is trying to access a REST endpoint with Basic Authentication enabled. When it makes it's GET request, Chrome is first preflighting the request, but is receiving a 403 Forbidden response from the server:
Request URL:http://dev.mydomain.com/joeV2/users/listUsers
Request Method:OPTIONS
Status Code:403 Forbidden
Request Headers:
OPTIONS /joeV2/users/listUsers HTTP/1.1
Host: dev.mydomain.com
Connection: keep-alive
Cache-Control: max-age=0
Access-Control-Request-Method: GET
Origin: http://localhost:8000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36
Access-Control-Request-Headers: accept, authorization
Accept: */*
Referer: http://localhost:8000/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Response Headers:
HTTP/1.1 403 Forbidden
Date: Sat, 15 Feb 2014 02:16:05 GMT
Content-Type: text/plain; charset=UTF-8
Content-Length: 0
Connection: close
I'm not entirely sure how to proceed. The Tomcat filter, by default, accepts the OPTIONS header to access the resource.
The problem, I believe, is that my resource (the request URL) http://dev.mydomain.com/joeV2/users/listUsers is configured to only accept GET methods:
#RequestMapping( method=RequestMethod.GET, value="listUsers", produces=MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public List<User> list(){
return userService.findAllUsers();
}
Does this mean that I must make that method/endpoint accept OPTIONS method as well? If so, does that mean I have to explicitly make every REST endpoint accept the OPTIONS method? Apart from cluttering code, I'm confused how that would even work. From what I understand the OPTIONS preflight is for the browser to validate that the browser should have access to the specified resource. Which I understand to mean that my controller method should not even be called during the preflight. So specifying OPTIONS as an accepted method would be counter-productive.
Should Tomcat be responding to the OPTIONS request directly without even accessing my code? If so, is there something missing in my configuration?
I sat down and debugged through the org.apache.catalina.filters.CorsFilter to figure out why the request was being forbidden. Hopefully this can help someone out in the future.
According to the W3 CORS Spec Section 6.2 Preflight Requests, the preflight must reject the request if any header submitted does not match the allowed headers.
The default configuration for the CorsFilter cors.allowed.headers (as is yours) does not include the Authorization header that is submitted with the request.
I updated the cors.allowed.headers filter setting to accept the authorization header and the preflight request is now successful.
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization</param-value>
</init-param>
</filter>
Of course, I'm not sure why the authorization header is not by default allowed by the CORS filter.
The first thing I would try is to set your common headers for your http requests that angular dispatches, by inserting the following config block on your module:
.config(function($httpProvider){
$httpProvider.defaults.headers.common = {};
$httpProvider.defaults.headers.post = {};
$httpProvider.defaults.headers.put = {};
$httpProvider.defaults.headers.patch = {};
})
These are supposed to be set by default already, but I've found that I often have to do this manually in my config due to any overrides from other modules or internal angular bootstraping process.
Your CORS filter should be enough on the server side to allow these types of requests, but sometimes, you need to specify request methods in addition to your origins, as well as accepted content types. The tomcat docs have this advanced block, which addresses those.
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
<param-name>cors.support.credentials</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.preflight.maxage</param-name>
<param-value>10</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
If the first doesn't work on it's own, try enhancing your filters, especially:
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>

BlobStore Redirects being ignored by ServletModule wired servlets

After the blobstore handles the upload request of a file it redirects to the url it is given, in this case "/upload". If I configure the UploadServlet url in web.xml like this:
<servlet>
<servlet-name>uploadServlet</servlet-name>
<servlet-class>com.....servlet.UploadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>uploadServlet</servlet-name>
<url-pattern>/upload</url-pattern>
</servlet-mapping>
It works. If I use Guice to wire the servlet:
serve("/upload").with(UploadServlet.class);
I get the error:
Problem accessing /upload. Reason:NOT_FOUND
It seems as though the com.google.inject.servlet.ServletModule does not handle redirects. Is there a way around this?
I have struggled with the same issue myself today. This solved my problem and may be related:
https://groups.google.com/forum/#!topic/google-appengine-java/oqfvEmZGrdw
In dev mode, the blobstore service uses
RequestDispatcher.forward() rather than an HTTP request:
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
Of course, may be too late for you but for others it might help :-)

encounter "Error configuring application listener of class org.directwebremoting.servlet.DwrListener"

i found the error of "Error configuring application listener of class org.directwebremoting.servlet.DwrListener" when deploying application using dwr in tomcat6.
Here is my web.xml
<display-name>DWR (Direct Web Remoting)</display-name>
<description>A Simple Demo DWR</description>
<listener>
<listener-class>org.directwebremoting.servlet.DwrListener</listener-class>
</listener>
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<display-name>DWR Servlet</display-name>
<description>Direct Web Remoter Servlet</description>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<!-- This should NEVER be present in live -->
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<!-- Remove this unless you want to use active reverse ajax -->
<init-param>
<param-name>activeReverseAjaxEnabled</param-name>
<param-value>true</param-value>
</init-param>
<!-- By default DWR creates application scope objects when they are first
used. This creates them when the app-server is started -->
<init-param>
<param-name>initApplicationScopeCreatorsAtStartup</param-name>
<param-value>true</param-value>
</init-param>
<!-- WARNING: allowing JSON-RPC connections bypasses much of the security
protection that DWR gives you. Take this out if security is important -->
<init-param>
<param-name>jsonRpcEnabled</param-name>
<param-value>true</param-value>
</init-param>
<!-- WARNING: allowing JSONP connections bypasses much of the security
protection that DWR gives you. Take this out if security is important -->
<init-param>
<param-name>jsonpEnabled</param-name>
<param-value>true</param-value>
</init-param>
<!-- data: URLs are good for small images, but are slower, and could OOM for
larger images. Leave this out (or keep 'false') for anything but small images -->
<init-param>
<param-name>preferDataUrlSchema</param-name>
<param-value>false</param-value>
</init-param>
<!-- This enables full streaming mode. It's probably better to leave this
out if you are running across the Internet -->
<init-param>
<param-name>maxWaitAfterWrite</param-name>
<param-value>-1</param-value>
</init-param>
<init-param>
<param-name>org.directwebremoting.extend.ServerLoadMonitor</param-name>
<param-value>org.directwebremoting.impl.PollingServerLoadMonitor</param-value>
</init-param>
<!--
For more information on these parameters, see:
- http://getahead.org/dwr/server/servlet
- http://getahead.org/dwr/reverse-ajax/configuration
-->
<load-on-startup>1</load-on-startup>
</servlet>
Are you are getting a ClassNotFound error as well ?
Have you placed dwr.jar in the WEB-INF/lib directory of your webapp?

Resources