Kotlin Spring Boot CORS "No mapping for OPTIONS /users" - spring-boot

I have tried every solution I could find on stack overflow for my problem but nothing worked.
I have a CORS configuration in my kotlin app.
#Configuration
#EnableWebMvc
class WebConfig : WebMvcConfigurer {
override fun addCorsMappings(registry: CorsRegistry) {
registry.addMapping("/**")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedOrigins("*")
.allowedHeaders("*");
}
}
And I have this controller:
#RestController
#RequestMapping("users")
class UserController(
val userService: UserService
) {
#CrossOrigin
#PostMapping("/", produces = ["application/json"])
fun createUser(#RequestBody user: User): User {
return userService.createUser(user)
}
}
When I call that endpoint from my Angular application I get the following error:
WARN 19441 --- [nio-8080-exec-2] o.s.web.servlet.PageNotFound : No mapping for OPTIONS /users
I can't seem to have the Global CORS working. How have you done this in Kotlin?
Thank you!

The URL you are calling is incorrect.
In your #PostMapping you registered /users/ and not /users.
To fix this change your post mapping to #PostMapping(produces = ["application/json"]) and it should be working.

Related

Spring Cloud APIGW, Spring Boot and OpenAPI issue - CORS issue

I am using Spring Boot and Microservices stack using Spring Cloud APIGW. I am using the same code mentioned here: https://piotrminkowski.com/2020/02/20/microservices-api-documentation-with-springdoc-openapi/
When I hit any endpoint, I don't see response is coming and getting below error.
Access to fetch at 'http://192.168.0.2:49382/' from origin 'http://localhost:8060' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Source code: https://github.com/piomin/sample-spring-microservices-new
I was able to fix it by myself looking at suggestion here: Spring Cloud Gateway and Springdoc OpenAPi integration and https://github.com/springdoc/springdoc-openapi/issues/1144
I had to add below in apigw-service in application.properties file
server:
forward-headers-strategy: framework
Also, in each microservice, you need to add below bean
#Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH");
}
};
}
You should add swagger configuration
#Configuration
#OpenAPIDefinition(servers = {
#Server(url = "/", description = "Default Server URL")
})
public class SwaggerConfiguration {
#Bean
public OpenAPI customOpenAPI(#Value("springdoc-openapi-ui") String serviceTitle, #Value("1.6.12") String serviceVersion) {
final String securitySchemeName = "bearerAuth";
return new OpenAPI()
.components(
new Components().addSecuritySchemes(
securitySchemeName,
new SecurityScheme()
.type(SecurityScheme.Type.HTTP)
.scheme("bearer")
.bearerFormat("JWT")
)
)
.security(List.of(new SecurityRequirement().addList(securitySchemeName)))
.info(new Info().title(serviceTitle).version(serviceVersion));
}
}

Vaadin: Disable HTTP PUT/DELETE requests

I'm running Vaadin on Spring-Boot.
I tried implementing WebMvcConfigurer & and HandlerInterceptor to disable PUT & DELETE requests, but it is not working. I can see WebMvcConfigurer is getting loaded, but the preHandle method in the custom HandlerInterceptor never gets called.
I noticed Vaadin is loading AtmosphereInterceptor, wondering if that is overriding my custom spring settings.
Any idea what can I do to disable PUT & DELETE on all paths (/**) by default in vaadin?
edit code:
#Component
class HTTPRequestInterceptor extends HandlerInterceptor {
override def preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean = {
if (HttpMethod.GET.matches(request.getMethod) || HttpMethod.POST.matches(request.getMethod)) {
true
} else {
response.sendError(HttpStatus.METHOD_NOT_ALLOWED.value())
false
}
}
}
#Configuration
class HTTPRequestInterceptorConfig (#Autowired interceptor: HTTPRequestInterceptor) extends WebMvcConfigurer {
private val log = LoggerFactory.getLogger(classOf[HTTPRequestInterceptorConfig])
override def addInterceptors(registry: InterceptorRegistry): Unit = {
log.info("adding interceptors")
registry.addInterceptor(interceptor).addPathPatterns("/**")
}
}
Note: I tried both with & without #Autowired parameter.

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

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?

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.

Resources