Using 'application/json', given [*/*] and supported [application/json] - spring-boot

I have a spring boot app (2.3.0.M2) running on aws. While accessing it from local react app running on localhost:3000, I was getting following error:
Access to XMLRequest at aws-url from origin localhost:3000 has been blocked by CORS policy: Response to preflight request doesn't pass access control check: `Access-Control-Allow-Origin` header is present on the request resource.
I tried to solve it by adding the CORS policy to the spring boot app, by adding a WebConfig as below:
#Configuration
#EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
And now getting Using 'application/json', given [*/*] and supported [application/json] after cors policy updated. Using 'application/vnd.spring-boot.actuator.v3+json', given [*/*] and supported [application/vnd.spring-boot.actuator.v3+json, application/vnd.spring-boot.actuator.v2+json].
I have also tried specifically defining the core policies for content-type(as application/json). And tried removing the produces=content-type from controller, which is not a great idea but it doesn't work.
It goes to the controller, and fails at the return statement. This is how the controller looks:
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
#RestController
public class SomeController {
#ResponseStatus(HttpStatus.OK)
#GetMapping(value = "/{id}", produces = APPLICATION_JSON_VALUE)
public Object get(#PathVariable("id") Long id) {
return service.get(id);
}
}
What am I missing? any captain to rescue?

Related

How to get Application properties configuration into Annotation as parameter

I want to use #CrossOrigin annotation on my RestController in my Spring Boot application and set origins parameter with the values from application.properties file.
#CrossOrigin(origins = {"${app.cors.origins}"})
public class SomeController(){
//
//
}
I set the property in my application.properties file like
app.cors.origins =http://www.google.com,http://localhost:8001
However that doesn't work as a cross origin request from http://localhost:8001 to my app fails with CORS error on the browser.
Am I missing something on setting the property?
Update : Problem is to set origins as a string array from the value of application property entry. When I hardcode the urls in origin, it works.
Thanks
If you want to use application.properties to set origins of CORS then this is the solution.
#Configuration
public class WebMvcConfig implements WebMvcConfigurer {
#Value("${app.cors.origins}")
private String corsAllowedOrigins;
#Value("${app.cors.methods}")
private String corsAllowedMethods;
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins(corsAllowedOrigins)
.allowedMethods(corsAllowedMethods);
}
application.properties
app.cors.origins=http://www.google.com,http://localhost:8001
app.cors.methods=GET,OPTIONS
I'm also working on this issue, I found another post mentioned about controller level parameter annotation for Cors. I haven't try it yet. share it with you:
Create your custom annotation and annotate the API with that.
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.METHOD})
#CrossOrigin
public #interface CrossOriginsList {
public String[] crossOrigins() default {
"http://domain1.com", "http://domain1.com"
"http://domain1.com", "http://domain1.com"
// Pass as many as you want
};
}
And now Annotate your API with this custom Annotation
#CrossOriginsList
public String methodName() throws Exception
{
//Business Logic
}

Wrong CORS configuration in a SpringBoot project

I'm developing a CRUD app that will serve REST in the SpringBoot part (it will have an Angular part too, consuming JSON). The SpringBoot part serves gracefully JSON (queries against a MySQL database) but when I run the part that tries to delete a record I get a 405 error:
"There was an unexpected error (type=Method Not Allowed, status=405)."
This is the code that fails (it's calling a #Service)
#RequestMapping(value = "/avisos/delete/{id}", method = RequestMethod.DELETE)
public ResponseEntity<Void> borraAviso(#RequestParam("id") Long id) {
boolean isRemoved;
isRemoved = avisoService.borraAviso(id);
if (!isRemoved) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
else
return new ResponseEntity<>(HttpStatus.OK);
}
This is the CORS configuration file:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
#Configuration
public class CorsConfiguration implements WebMvcConfigurer
{
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:4200")
//.allowedMethods("GET", "POST");
.allowedMethods("");
}
}
The program runs in a Linux Mint box but I have tested that in a W8 box too and I get the same error.
(I'm using Spring Tool Suite 4, Version: 4.8.0.RELEASE, and Maven).
The declaration of the method has one issue
#RequestMapping(value = "/avisos/delete/{id}", method =
RequestMethod.DELETE) public ResponseEntity
borraAviso(#RequestParam("id") Long id) {
Here the id is a PathVariable. So the correct declaration would be
#RequestMapping(value = "/avisos/delete/{id}", method = RequestMethod.DELETE)
public ResponseEntity<Void> borraAviso(#PathVariable("id") Long id) {
By default, GET, HEAD, POST method are allowed for CORS if not overridden.
If you want to allow DELETE method, then the following config should work.
registry.addMapping("/**")
.allowedOrigins("http://localhost:4200")
.allowedMethods(HttpMethod.GET.name(),
HttpMethod.HEAD.name(),
HttpMethod.POST.name(),
HttpMethod.DELETE.name()
);

Spring Boot - Cross-Origin Request Blocked (Reason: CORS header ‘Access-Control-Allow-Origin’ missing)

I have this mapping:
User 1----------------------------* Expertises
I'm using the controller SpringBoot, My contoller is
#RestController
#CrossOrigin(origins = "http://localhost:4200", "http://localhost:6227")
#RequestMapping("/api/auth")
public class UserController
{
#PostMapping("/signup/{expertises}")
public ResponseEntity<String> registerUser(#Valid #RequestBody SignUpForm signUpRequest, #PathVariable List<String> expertises)
{
}
}
I add the annotation #CrossOrigin to all the repositories
#CrossOrigin(origins = {"http://localhost:4200", "http://localhost:6227"}, methods = { RequestMethod.GET, RequestMethod.POST, RequestMethod.DELETE }, maxAge = 3600)
#Repository
public interface UserRepository extends JpaRepository<User, Long> {}
The main class is:
#SpringBootApplication
public class SpringBootJwtAuthenticationApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootJwtAuthenticationApplication.class, args);
}
#Bean
public WebMvcConfigurer configurer()
{
return new WebMvcConfigurer()
{
#Override
public void addCorsMappings(CorsRegistry registry)
{
registry.addMapping("/*")
.allowedOrigins("http://localhost:4200", "http://localhost:6227");
}
};
}
}
I added the file MyConfiguration (as Sir Ananthapadmanabhan proposed)
Front-End (Angular6)
So I want to add a list of expertises to one user using this method:
onSubmit()
{
this.submitted = true;
console.log('---------SelectedExpertise:' + this.selectedExpertiseCheckBox);
this.userService.signUpUser(this.user,
this.selectedExpertiseCheckBox)
.subscribe(data => console.log("---------------Create user:" + data)
,error => console.log(error));
this.user = new User();
}
where
signUpUser(value: any, listExp: String[]): Observable<Object>
{
return this.http.post(`${this.baseUrl}/signup/${listExp}`, value);
}
I can't do that cause adding the list of expertises. That produces this error
Have you please any idea about solving that ?.
Thanks.
As indicated on the console; it was a problem with CORS.
But in reality, it wasn't.
In fact, this bug is caused by a bad use of localStorage with front-end:
the list of strings have to be called like that:
var storedExpertises = JSON.parse(localStorage.getItem("explib"));
and not like that:
localStorage.getItem("explib")
Big thanks Sir #Ananthapadmanabhan for your help and advices.
You have enabled CORS for the endpoint http://localhost:4200 on port address 4200. But it seems you are running the angular 6 app separately on local and the request is being made from the port address 6227 , which might be causing the issue since the CORS policy that you have enabled only allows same origin. Try adding the following in CORS :
#CrossOrigin(origins = "http://localhost:6227")
and if you are still having issues with , Cross-Origin Request Blocked (Reason: CORS header ‘Access-Control-Allow-Origin’ missing) then check this post :
CORS policy conflict in Spring boot
Even through you have enabled the CORS. The requests from different ports will not go through. You need to enable HTTP.OPTIONS.

Spring + restful + cors + not func

I am having a problem in my restful service with spring. Even after enabling CORS, I can not connect to my angular application.
#CrossOrigin
public class UsuarioController {
#Autowired
UsuarioService service;
#RequestMapping(method = RequestMethod.GET, value = "/lista_todos_usuarios", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Collection<Usuario>> buscaTodosUsuarios() {
Collection<Usuario> usuarios = service.buscaTodosUsuarios();
return new ResponseEntity<>(usuarios, HttpStatus.OK);
}
}
From Enabling Cross Origin Requests for a RESTful Web Service
In your case, I think you need indicate what origin is allowed to access the service.
In the example, the origin is http://localhost:9000. It should correspond to your Angular application.
Enabling CORS
Controller method CORS configuration
So that the RESTful web service will include CORS access control
headers in its response, you just have to add a #CrossOrigin
annotation to the handler method:
src/main/java/hello/GreetingController.java
#CrossOrigin(origins = "http://localhost:9000")
#GetMapping("/greeting")
public Greeting greeting(#RequestParam(required=false, defaultValue="World") String name) {
System.out.println("==== in greeting ====");
return new Greeting(counter.incrementAndGet(), String.format(template, name));
}
As a very simple workaround I could recommend to install CORS extension plugin for Chrome and use it during initial development stages.
If you want a global configuration, you may override method addCorsMappings of WebMvcConfigurerAdapter in your web configuration:
#Configuration
#EnableWebMvc
public class DispatcherContext extends WebMvcConfigurerAdapter {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("GET", "POST", "PUT", "PATCH", "DELETE", "HEAD");
}
}
Thanks Nikolay, sometimes we miss out on obvious things. Hehehe
in fact, I forgot to annotate the class with #RestController.

Spring Annotation-Based Interceptor

can any of you please post a snippet for the following. I've looked in a couple of places but they all seem to be xml based. I'd like to have this code in java configuration style only.
I am trying to accomplish the following..
1) I need to intercept a specific url, for example "http://localhost:8080/test" and only a url that starts with "/test/*". This is not a spring security question, this is just for an endpoint I like to intercept.
2) I need to intercept the HttpServletRequest object of that request and add a specific header to that request. For example, "authorization", "bearer xxxx".
3) When the /test endpoint finally hits, I should be able to see the authorization header inside my HttpServletRequest object.
Thank you guys.
you can do this like this:
(Whithin "YourOwnInterceptor" you can add the value to the header...)
#Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {
#Bean
public YourOwnInterceptor yourOwnInterceptor() {
return new YourOwnInterceptor();
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
super.addInterceptors(registry);
registry.addInterceptor(yourOwnInterceptor()).
addPathPatterns("/<your-url-to-intercept>/**");
}
}

Resources