Enabling Cross Origin Resource Sharing for Spring Data Rest - spring

I'm developing Spring (non-Boot) application with Spring 4.2.1 version. I've enabled CORS for Spring MVC in web configuration file.
#Configuration
#EnableWebMvc
#ComponentScan({"com.hello.web", "com.hello.rest"})
#Import(RestMvcConfig.class)
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
And it was working correct. But now i started to use String Data Rest 2.4 and integrated it with Spring MVC. How to enable Cross Origin Resources Sharing for Spring Data Rest controllers? I've tried to fix it with filter bean Spring Data Rest and Cors
#Configuration
public class RestMvcConfig extends RepositoryRestMvcConfiguration {
#Override
public RepositoryRestConfiguration config() {
RepositoryRestConfiguration config = super.config();
config.setBasePath("/api");
config.setDefaultMediaType(new MediaType("application", "json", Charset.forName("utf-8")));
return config;
}
#Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true); // you USUALLY want this
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
But CORS is still not allowed.
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 403.
How to enable CORS for Spring Data Rest?

Related

How to enable CORS in Spring

I tried doing this but it isn't working. I also tried adding #CrossOrigin on top of my controller class but that didn't work either.
#Configuration
public class CorsConfig {
#Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*"); //'*' allows all endpoints, Provide your URL/endpoint, if any.
config.addAllowedHeader("*");
config.addAllowedMethod("POST"); //add the methods you want to allow like 'GET', 'PUT',etc. using similar statements.
config.addAllowedMethod("GET");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
There are several ways to achieve that. You can do that on method level or global. For Example (source: https://www.baeldung.com/spring-cors):
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
#Configuration
#EnableWebMvc
public class CorsConfiguration implements WebMvcConfigurer
{
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("GET", "POST");
}
}
also take a look on the old thread: How to configure CORS in a Spring Boot + Spring Security application?
#Configuration
public class CorsConfig {
#Bean
public WebMvcConfigurer corsConfig() {
return new WebMvcConfigurer() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS")
.allowedOrigins("*")
.allowedHeaders("*")
.allowCredentials(false);
}
};
}
}
Try this once, it should work.

How to fix Cors error Access-Control-Allow-Origin missing

I have a spring boot rest application and I am not using Spring security. My rest service looks like this
#RestController
#CrossOrigin
public class AuthenticationService {
...
#GetMapping(path = "/getUser")
public JSONObject getUser() {
...
}
}
I call the API from a REST application using axios get. Everything works fine locally.
But when the application is deployed on cloud as a docker image, I get the 403 error
(Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
Even when I add a CorsConfiguration file I get the same error.
#Configuration
public class CorsConfiguration {
#Bean
public WebMvcConfigurer corsConfigurer()
{
return new WebMvcConfigurer() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*")
.allowedHeaders("Accept", "Origin", "X-Requested-With,Content-Type", "Authorization", "X-XSRF-Header")
.allowCredentials(true);
}
};
}
}
I have spent a lot of time to find a solution for this but somehow it isn't working.
Declaring a bean works fine for me:
#Configuration
public class WebConfigurer implements ServletContextInitializer, WebMvcConfigurer {
private final Environment env;
private final MyProperties properties;
public WebConfigurer(Environment env, MyProperties properties) {
this.env = env;
this.properties = properties;
}
#Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = properties.getCors();
if (config.getAllowedOrigins() != null && !config.getAllowedOrigins().isEmpty()) {
log.debug("Registering CORS filter");
source.registerCorsConfiguration("/api/**", config);
source.registerCorsConfiguration("/management/**", config);
source.registerCorsConfiguration("/v3/api-docs", config);
}
return new CorsFilter(source);
}
}
Yaml properties:
# CORS is only enabled by default with the "dev" profile
cors:
allowed-origins: '*'
allowed-methods: '*'
allowed-headers: '*'
exposed-headers: 'Authorization,Link,X-Total-Count'
allow-credentials: true
max-age: 1800
fixed by adding spring security

Spring Security CORS doesn't work for Http PUT method

I am getting 'Invalid CORS request' when I try to PutMapping of my API in Postman. But it is working fine for 'POST' and 'GET' mapping.
Why is it not working for the 'PUT' operation?
My Spring Boot version: 2.0
This is my config:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/h2-console/**/**").permitAll()
.antMatchers(HttpMethod.GET,"/user/get-request").permitAll()
.antMatchers(HttpMethod.POST,"/user/post-request").permitAll()
.antMatchers(HttpMethod.PUT,"/user/put-request").permitAll()
.and()
.exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint)
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.addFilter(new JwtAuthorizationFilter(authenticationManager(), jwtUserDetailService));
}
#Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*").allowedHeaders("*").exposedHeaders("Authorization");
}
};
}
This is my controller :
#RestController
#RequestMapping("/user")
public class UserController {
#PutMapping("/put-request")
public void doResetPassword(#RequestBody String password) {
System.out.println("PUT MAPPING");
}
#PostMapping("/post-request")
public void doResetPassword(#RequestBody String password) {
System.out.println("POST MAPPING");
}
#GetMapping("/get-request")
public void doResetPassword() {
System.out.println("GET MAPPING");
}
}
It's much simpler than the accepted solution.
#Configuration
public class CrossOriginConfig {
#Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry
.addMapping("/**")
.allowedMethods("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS");
}
};
}
}
#Bean
public CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(ImmutableList.of("*"));
configuration.setAllowedMethods(ImmutableList.of("HEAD",
"GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(ImmutableList.of("*"));
configuration.setExposedHeaders(ImmutableList.of("X-Auth-Token","Authorization","Access-Control-Allow-Origin","Access-Control-Allow-Credentials"));
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
I managed to allow cors request by adding this bean. You can configure setAllowedHeaders() and setExposedHeaders() by your need.
Also, I added this line to my controller;
#RequestMapping(value = "/auth")
#RestController
#CrossOrigin(origins = "*") //this line
public class AuthenticationController {..}
If your controller needs to handle on-the-fly OPTION request you can add this method to your controller. You can configure the value by your endpoint.
#RequestMapping(value = "/**/**",method = RequestMethod.OPTIONS)
public ResponseEntity handle() {
return new ResponseEntity(HttpStatus.OK);
}
If you are using a IIS server It was a problem with the WebDAVModule which seems to block PUT and DELETE methods by default!
<system.webServer>
<modules runAllManagedModulesForAllRequests="false">
<remove name="WebDAVModule" />
</modules>
</system.webServer>
I really hope no one else pain with that! =]
Fonte: https://mozartec.com/asp-net-core-error-405-methods-not-allowed-for-put-and-delete-requests-when-hosted-on-iis/
In Spring with Kotlin I did the following:
#Bean
fun corsConfigurationSource(): CorsConfigurationSource? {
val source = UrlBasedCorsConfigurationSource()
val corsConfig = CorsConfiguration()
.applyPermitDefaultValues()
.setAllowedOriginPatterns(listOf("*"))
corsConfig.addAllowedMethod(HttpMethod.PUT)
source.registerCorsConfiguration("/**", corsConfig)
return source
}
I just want to add 3 things.
The accepted answer and the one below it are wrong ways of doing CORS.
If you are trying to configure CORS, that means you are trying to make your API accessible only by a number of clients you know. The lines
configuration.setAllowedOrigins(ImmutableList.of("*")); // from the first answer
.addMapping("/**") // from the second answer
make the API accessible by any client. If that is what you want, you can just do the following with out a need to configure another bean
http.cors().disable()
The issue in the question may happen when you allow origins with http and do your request using https. So be aware that those 2 are different.
Below is a working configuration
// In the import section
import static org.springframework.security.config.Customizer.withDefaults;
// In the HttpSecurity configuration
http.cors(withDefaults())
#Bean
public CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200", "https://localhost:4200"));
configuration.setAllowedMethods(Arrays.asList("HEAD",
"GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(Arrays.asList("Content-Type", "X-Auth-Token","Authorization","Access-Control-Allow-Origin","Access-Control-Allow-Credentials"));
configuration.setExposedHeaders(Arrays.asList("Content-Type", "X-Auth-Token","Authorization","Access-Control-Allow-Origin","Access-Control-Allow-Credentials"));
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
I'm using Spring Security and Spring Boot 2.1.2. In my specific case, the PUT call worked after I explicitly declared the "PUT" method in the setAllowedMethods() from CorsConfigurationSource bean. The headers can be chosen depending on the application behavior.
#Bean
CorsConfigurationSource corsConfigurationSource() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final String headers = "Authorization, Access-Control-Allow-Headers, "+
"Origin, Accept, X-Requested-With, Content-Type, " +
"Access-Control-Request-Method, Custom-Filter-Header";
CorsConfiguration config = new CorsConfiguration();
config.setAllowedMethods(Arrays.asList("GET","POST","PUT","DELETE")); // Required for PUT method
config.addExposedHeader(headers);
config.setAllowCredentials(true);
config.applyPermitDefaultValues();
source.registerCorsConfiguration("/**", config);
return source;
}

Enabling CORS in Spring Secondary Servlet

I am registering a secondary servlet using Spring boot's ServletRegistrationBean
#Configuration
public class CxfServletRegister {
#Bean
public ServletRegistrationBean getODataServletRegistrationBean() {
ServletRegistrationBean odataServletRegistrationBean = new ServletRegistrationBean(new CXFNonSpringJaxrsServlet(), "/odata.svc/*");
Map<String, String> initParameters = new HashMap<String, String>();
initParameters.put("javax.ws.rs.Application", "org.apache.olingo.odata2.core.rest.app.ODataApplication");
initParameters.put("org.apache.olingo.odata2.service.factory", "com.cce.utils.JPAServiceFactory");
odataServletRegistrationBean.setInitParameters(initParameters);
return odataServletRegistrationBean;
}
}
I am building an OData application using Apache Olingo. I want CORS to be enabled for my service.
How do I enable CORS for this servlet?
PS I have tried the WebConfigurer bean from the Spring: Getting Started guides
#Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/greeting-javaconfig").allowedOrigins("*");
}
};
}
This doesn't work, probably because this is configuring spring web's default dispatcher servlet and not the additional servlet configured using the ServletRegistrationBean
I found a likely way to do it here:
https://spring.io/blog/2015/06/08/cors-support-in-spring-framework
#Configuration
public class MyConfiguration {
#Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("http://domain1.com");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}

Enable CORS On Spring accessing MongoDB data

I'm trying to develop a RestFul Web Service with Spring, that fetches data from a mongoDB collection and serves it to a client. To build the service i followed this guide on spring.io. Everything went well, i can access data from mongoDB and search it for the data structure name.
The troubles began when i tried to manage requests from my client, i receive classical error of same-domain-policy violation.
No 'Access-Control-Allow-Origin' header is present on the requested
resource.
The project is EXTREMELY simple, is composed of those 3 classes:
Frames.java
#Id
private String Id;
private String frameName;
private ArrayList<String> frameElements;
public String getId() {
return Id;
}
public String getFrameName() {
return frameName;
}
public ArrayList<String> getFrameElements() {
return frameElements;
}
FrameRestFulServiceApplication.java
#SpringBootApplication
public class FrameRestFulServiceApplication {
public static void main(String[] args) {
SpringApplication.run(FrameRestFulServiceApplication.class, args);
}
}
FramesRepository.java
#RepositoryRestResource(collectionResourceRel = "frames", path = "frames")
public interface FramesRepository extends MongoRepository<Frames, String>{
List<Frames> findByFrameNameLike(#Param("frameName") String frameName);
List<Frames> findByFrameName(#Param("frameName") String frameName);
}
I tried different methods found in the documentation See here but without results...
A similar question is Spring Data Rest and Cors
The answer is that if you are using Spring Boot (which supports Filter beans), it could be something like:
#Configuration
public class RestConfiguration {
#Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true); // you USUALLY want this
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
have you tried to add a class like this?
#Configuration
#EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
it worked for me

Resources