Finatra access-control-allow-origin

1.3k Views Asked by At

I try to access my REST API that I built using Finatra via AJAX calls. Unfortunately, I get the following error:

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

I have read about enabling CORS, but I could not find out how to do this in Finatra 2.1.6. I have seen that there is a policy that could be enabled and is very permissive, but I somehow do not manage to get it running. In my code I wrote:

override def configureHttp(router: HttpRouter) {
  router
    .filter(new HttpFilter(Cors.UnsafePermissivePolicy))
    .add(controller)
}

How can I set the headers properly to allow CORS in Finatra?

2

There are 2 best solutions below

0
On

Apart from the CorsFilter, you need to add a controller to manage all the preflighted OPTIONS requests(please reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests), something like this:

class CorsController extends Controller {
   options("/api/:*") {
     _: Request => response.ok
   }
}

if not the preflighted requests will not be handled.

0
On

It is possible to add, general application filters, per controller filters or even action filters. Have a look at this filters section in finatra.

Its possible to go with a per-controller filter approach to solve the Cors issue. In the Server.scala file it's defined a filter:

import com.twitter.finagle.{Filter, Service, SimpleFilter}

class CorsFilter extends SimpleFilter[Request, Response] { 
    override def apply(request: Request, service: Service[Request, Response]): Future[Response] = {

        service(request).map {
            response => response.headerMap
              .add("access-control-allow-origin", "*")
              .add("access-control-allow-headers", "accept, content-type")
              .add("access-control-allow-methods", "GET,HEAD,POST,DELETE,OPTIONS,PUT,PATCH")

            response
        }
}

then, in the section where you define your server, register the controllers and attach to it the filter you just created:

object ServerMain extends Server

class Server extends HttpServer {

  override val name = "com.example.server"

  override def configureHttp(router: HttpRouter) {
    router          
      .filter[CommonFilters]
      .filter[LoggingMDCFilter[Request, Response]]
      .filter[TraceIdMDCFilter[Request, Response]]          
      .add[CorsFilter, MainController] // see the CorsFilter here    
  }
}

I hope it helps.