[MGNLREST-81] CORS preflight requests are throwing DefaultOptionsMethodException: No resource method found for options Created: 30/Nov/16  Updated: 12/Apr/21  Resolved: 31/Jul/20

Status: Closed
Project: Magnolia REST Framework
Component/s: integration
Affects Version/s: 1.1.2
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Edwin Guilbert Assignee: Unassigned
Resolution: Duplicate Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Java 1.8.0_45
Tomcat 7.0.64


Attachments: Java Source File RestCorsFilter.java     File contactList.ftl     File contactList.yaml     Text File restEasyException.log    
Issue Links:
Relates
relates to MAGNOLIA-7215 CORS & OPTIONS Pre-flight support Closed
duplicate
duplicates MGNLREST-193 Need configurable preflight OPTIONS f... Closed
Template:
Acceptance criteria:
Empty
Task DoD:
[ ]* Doc/release notes changes? Comment present?
[ ]* Downstream builds green?
[ ]* Solution information and context easily available?
[ ]* Tests
[ ]* FixVersion filled and not yet released
[ ]  Architecture Decision Record (ADR)
Bug DoR:
[ ]* Steps to reproduce, expected, and actual results filled
[ ]* Affected version filled
Date of First Response:

 Description   

When using CORS for REST requests, the rest easy integration module is throwing an exception in case of non-simple preflight requests. For example when issuing a GET request with custom headers from a different domain.

Exception thrown (Full stacktrace attached):

ERROR info.magnolia.rest.RestExceptionMapper            : Exception thrown executing REST endpoint, returning 500
org.jboss.resteasy.spi.DefaultOptionsMethodException: No resource method found for options, return OK with Allow header
	at org.jboss.resteasy.core.registry.SegmentNode.match(SegmentNode.java:366)
	at org.jboss.resteasy.core.registry.SegmentNode.match(SegmentNode.java:114)
	at org.jboss.resteasy.core.registry.RootNode.match(RootNode.java:43)
	at org.jboss.resteasy.core.registry.RootClassNode.match(RootClassNode.java:48)
	at org.jboss.resteasy.core.ResourceMethodRegistry.getResourceInvoker(ResourceMethodRegistry.java:444)
	at org.jboss.resteasy.core.SynchronousDispatcher.getInvoker(SynchronousDispatcher.java:234)
	at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:171)

Steps to reproduce:

  1. Configure at least 2 different domains on your local. For example: www.test1.com and www.test2.com.
  2. Enable OPTIONS method in IPSecurityManager: /server/IPConfig/allow-all@methods:GET,POST,PUT,DELETE,OPTIONS
  3. Enable the unofficial Magnolia CORS filter with GET and OPTIONS as allowed methods: /server/filters/cors@allowMethods:GET, OPTIONS. Its important to configure properly the bypasses option. For example: pattern:/.rest to have it enabled for all rest requests.
  4. Give web access permissions (GET) for rest requests to rest role in Security app.
  5. Using www.test1.com as the public instance, create a page with the following AngularJS request:
    $http.get('http://www.test2.com:8080/magnoliaPublic/.rest/nodes/v1/workspace', {headers: {'TEST': 'TEST'}})
  6. The browser (Chrome in this example) will try to issue an OPTIONS request which will throw the exception attached.

An example AngularJS page is attached in order to test this scenario.

The step number 3 can be omitted and rest-integration will still throw the exception, just the CORS headers wont be added on the HTTP 500 response.

Its important to notice that this only happens when adding a custom header (or any other preflight use case) like TEST:TEST in this example. If the same request has no custom headers, the rest-integration module will exetute the resteasy endpoint correctly and the CORS filter will add the appropriate headers.



 Comments   
Comment by Edwin Guilbert [ 30/Nov/16 ]

As a quick fix, just by using the unofficial Magnolia CORS filter and registering the following class:

@PreMatching
public class RestCorsFilter implements ContainerRequestFilter
{
	@Override
	public void filter(ContainerRequestContext requestContext) throws IOException
	{
		if (requestContext.getMethod().equalsIgnoreCase("OPTIONS"))
		{
			Response.ResponseBuilder builder = Response.ok();
			requestContext.abortWith(builder.build());
		}
	}
}

in /modules/rest-integration/config/additionalProviders the exception is gone for this specific use case

Comment by Edwin Guilbert [ 30/Nov/16 ]

example java class for a quick fix

Comment by Viet Nguyen [ 24/Sep/18 ]

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

Comment by Mercedes Iruela [ 22/Aug/19 ]

5+2+3+5+5+0=20

Comment by Mikaël Geljić [ 03/Feb/20 ]

see also my comment on MAGNOLIA-7215; then CORS support may not be REST-specific anymore.

Generated at Mon Feb 12 06:56:24 CET 2024 using Jira 9.4.2#940002-sha1:46d1a51de284217efdcb32434eab47a99af2938b.