Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Wiki Markup
{span:style=font-size:2em;font-weight:bold} JAX-RS: CORS {span}


{toc}

h1. Introduction

CXF 2.5.1 introduces the [initial support|http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/cors/src/main/java/org/apache/cxf/rs/security/cors/] for the [Cross-Origin Resource Sharing|http://www.w3.org/TR/cors/] specification that "defines a mechanism to enable client-side cross-origin requests".

This [Mozilla.org page|https://developer.mozilla.org/en/http_access_control] provides a very good explanation of CORS.

Please see the [package.html|http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/cors/src/main/java/org/apache/cxf/rs/security/cors/package.html] for a good introduction to CORS and the way it is supported in CXF JAX-RS.

Note that the [CORS filter|http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/cors/src/main/java/org/apache/cxf/rs/security/cors/CrossOriginResourceSharingFilter.java] uses the JAX-RS selection algorithm to ensure that the JAX-RS resource method capable of handling the  request does exist.

h1. Maven dependencies

{code:xml}
<dependency>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-rt-rs-security-cors</artifactId>
  <version>2.6.1</version>
</dependency>
{code}

h1. Examples

Here is the test code showing how [CrossOriginResourceSharing|http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/cors/src/main/java/org/apache/cxf/rs/security/cors/CrossOriginResourceSharing.java] annotations can be applied at the resource and individual method levels:

{code:java}
@CrossOriginResourceSharing(
        allowOrigins = {
           "http://area51.mil:31415"
        }, 
        allowCredentials = true, 
        maxAge = 1, 
        allowHeaders = {
           "X-custom-1", "X-custom-2"
        }, 
        exposeHeaders = {
           "X-custom-3", "X-custom-4"
        }
)
public class AnnotatedCorsServer {
    @Context
    private HttpHeaders headers;

    @GET
    @Produces("text/plain")
    @Path("/simpleGet/{echo}")
    public String simpleGet(@PathParam("echo") String echo) {
        return echo;
    }
    
    @POST
    @Produces("application/json")
    @Consumes("application/json")
    @Path("/unannotatedPost")
    public Response postSomething() {
        return Response.ok().build();
    }

    @DELETE
    @Path("/delete")
    public Response deleteSomething() {
        return Response.ok().build();
    }

    // This method will do a preflight check itself, see a localPreflight property
    @OPTIONS
    @Path("/delete")
    @CrossOriginResourceSharing(
       localPreflight = true
    )
    public Response deleteOptions() {
        String origin = headers.getRequestHeader("Origin").get(0);
        if ("http://area51.mil:3333".equals(origin)) {
            return Response.ok()
                           .header(CorsHeaderConstants.HEADER_AC_ALLOW_METHODS, "DELETE PUT")
                           .header(CorsHeaderConstants.HEADER_AC_ALLOW_CREDENTIALS, "false")
                           .header(CorsHeaderConstants.HEADER_AC_ALLOW_ORIGIN, "http://area51.mil:3333")
                           .build();
        } else {
            return Response.ok().build();
        }
    }

    @GET
    @CrossOriginResourceSharing(
         allowOrigins = { "http://area51.mil:31415" }, 
         allowCredentials = true, 
         exposeHeaders = { "X-custom-3", "X-custom-4" }
    )
    @Produces("text/plain")
    @Path("/annotatedGet/{echo}")
    public String annotatedGet(@PathParam("echo") String echo) {
        return echo;
    }

    /**
     * A method annotated to test preflight.
     * 
     * @param input
     * @return
     */
    @PUT
    @Consumes("text/plain")
    @Produces("text/plain")
    @Path("/annotatedPut")
    public String annotatedPut(String input) {
        return input;
    }
}

{code}

The server configuration fragment:

{code:xml}

<beans>
        <bean id="cors-filter" class="org.apache.cxf.jaxrs.cors.CrossOriginResourceSharingFilter"/>

	<jaxrs:server id="service" address="/rest">
		<jaxrs:serviceBeans>
			<ref bean="cors-server" />
		</jaxrs:serviceBeans>
		<jaxrs:providers>
			<ref bean="cors-filter" />
		</jaxrs:providers>
	</jaxrs:server>

        <bean id="cors-server" scope="prototype" 
	      class="org.apache.cxf.systest.jaxrs.cors.AnnotatedCorsServer" /> 

</beans>

{code}