Ask Questions and Find Answers
Important:
Ask is now read-only. You can review any existing questions and answers, but not add anything new.
But - don't panic! While ask is no more, we've replaced it with discuss - the new Liferay Discussion Forum! Read more here here or just visit the site here:
discuss.liferay.com
Looking for a workaround for CORS when OAuth enabled with REST
Dear Community,
I have created some JAXRS services which work well. Then, I decided to apply some security using OAuth.
Using a Postman, I can perform any request without any issue but when sending same requests from an Angular application, it starts with an OPTION request for CORS (Cross Origin) and it fails with a 403. I disabled OAuth and added a filter to enable CORS
Then my requests work from my Angular App as the given filter allows CORS.
When enabling again OAuth, it fails again. It looks like the servlet request is being catched on top of this Filter (no log displayed anymore) and it doesn't work obviously.
With 6.2, we had to setup a filter at Tomcat web.xml but I assume things have improved.
Can anyone share with me any tips to solve this issue properly in the DXP way ?
Thank you,
I have created some JAXRS services which work well. Then, I decided to apply some security using OAuth.
Using a Postman, I can perform any request without any issue but when sending same requests from an Angular application, it starts with an OPTION request for CORS (Cross Origin) and it fails with a 403. I disabled OAuth and added a filter to enable CORS
@Component(property = { "osgi.jaxrs.extension=true",
"osgi.jaxrs.name=Filter.CORS" }, service = ContainerResponseFilter.class)
public class CorsFilter implements ContainerResponseFilter {
private Log _log = LogFactoryUtil.getLog(getClass());
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
throws IOException {
if (_log.isDebugEnabled()) {
_log.debug("Writing CORS headers");
}
MultivaluedMap<string, object> headers = responseContext.getHeaders();
headers.add("Access-Control-Allow-Origin", "*");
headers.add("Access-Control-Allow-Headers", "Origin,Content-Type,Accept,Authorization,content-type");
headers.add("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS,HEAD,PATCH");
headers.add("Access-Control-Max-Age", "1209500");
}
}</string,>
Then my requests work from my Angular App as the given filter allows CORS.
When enabling again OAuth, it fails again. It looks like the servlet request is being catched on top of this Filter (no log displayed anymore) and it doesn't work obviously.
With 6.2, we had to setup a filter at Tomcat web.xml but I assume things have improved.
Can anyone share with me any tips to solve this issue properly in the DXP way ?
Thank you,
Not sure if this helps you, but I usually do stuff like this in a reverse proxy. It's quite easy to do it there and also very flexible.
Note: It's not best practice to add "Access-Control-Allow-Origin: *" header, except maybe in development environments.
I usually use something like this. Basically a whitelist of domains that may access my service using cors. The same idea can, of course, be used in other implementations too.
https://stackoverflow.com/questions/1653308/access-control-allow-origin-multiple-origin-domains
Note: It's not best practice to add "Access-Control-Allow-Origin: *" header, except maybe in development environments.
I usually use something like this. Basically a whitelist of domains that may access my service using cors. The same idea can, of course, be used in other implementations too.
https://stackoverflow.com/questions/1653308/access-control-allow-origin-multiple-origin-domains
Hi Christoph,
Thank you for replying.
I know there are third party solutions such as reverse proxy but I want to find a solution with Liferay. This is also an approach to learn more about how the security works with Liferay.
I found some additional mechanisms.
First of all, It seems I can't avoid the CORS Filter. I understand that I should avoid giving access to any origin for security reason. But that component is required. Then, I need to add a new VerifierAuth in the pipeline otherwise my OPTIONS requests are rejected.
Can you please have a look at my source code that I am pleased to share with the community ?
https://github.com/Ajizan/liferay-cors
By the way, If I try to restrict the filter to a given URL using "auth.verifier.LiferayOptionsAuthVerifier.urls.includes", it doesn't apply. My REST service are deployed on /o/immobilio/... but if I set the above URL to "/o/immobilio/*" or even "/o/*", it doesn't work. And when I log the context path, it gives me "/o/immobilio", then I don't understand.
Thank you in advance for any feedbacks.
Thank you for replying.
I know there are third party solutions such as reverse proxy but I want to find a solution with Liferay. This is also an approach to learn more about how the security works with Liferay.
I found some additional mechanisms.
First of all, It seems I can't avoid the CORS Filter. I understand that I should avoid giving access to any origin for security reason. But that component is required. Then, I need to add a new VerifierAuth in the pipeline otherwise my OPTIONS requests are rejected.
Can you please have a look at my source code that I am pleased to share with the community ?
https://github.com/Ajizan/liferay-cors
By the way, If I try to restrict the filter to a given URL using "auth.verifier.LiferayOptionsAuthVerifier.urls.includes", it doesn't apply. My REST service are deployed on /o/immobilio/... but if I set the above URL to "/o/immobilio/*" or even "/o/*", it doesn't work. And when I log the context path, it gives me "/o/immobilio", then I don't understand.
Thank you in advance for any feedbacks.
Hello community,
I just upgraded to 7.1 GA4 and the code above doesn't work anymore.
It looks like the ContainerResponseFilter is no more taken into account even if the component is properly registered.
On the release notes, I haven't found any breaking change or anything related to ContainerResponseFilter, thus it is either a bug either a choice which has not been documented.
Can anyone help?
Thank you
I just upgraded to 7.1 GA4 and the code above doesn't work anymore.
It looks like the ContainerResponseFilter is no more taken into account even if the component is properly registered.
On the release notes, I haven't found any breaking change or anything related to ContainerResponseFilter, thus it is either a bug either a choice which has not been documented.
Can anyone help?
Thank you
After analyzing, it appears that Whiteboard became more strict. Now it requires to se target
Now it works
@Component(property = { "osgi.jaxrs.extension=true",
"osgi.jaxrs.name=LiferayCorsFilter", "osgi.jaxrs.application.select=(osgi.jaxrs.name=*)" }, immediate = true, configurationPid = "com.ajizan.liferay.cors.configuration.LiferayCORSConfiguration", service = ContainerResponseFilter.class)
Now it works
Copyright © 2025 Liferay, Inc
• Privacy Policy
Powered by Liferay™