Spring Boot CORS not working even after #CrossOrigin annotation - java

I have the following code that handles a CORS request
#CrossOrigin(origins = "*", methods = RequestMethod.PUT)
#RequestMapping(value = "/componentOrder", method = RequestMethod.PUT)
public #ResponseBody List<Map<String, Long>> syncComponentOrder(#PathVariable Long id,
#RequestBody List<Map<String, Long>> orders) { ... }
Even though Spring documentation says that this should handle a CORS request correctly but my Chrome still reports an error:
I need some help finding out why, the other CORS endpoints work perfectly.

Figured out why, this is not because the #CrossOrigin annotation, but rather I was missing a path parameter in my request, that's why I saw internal server error.
Strangely no error/warning is printed out, making it hard to debug.

Related

Spring CSRF unrestricted RequestMapping

Small question regarding a SonarQube scan on a SpringBoot project please.
I have a very simple handler, super simple, as follow:
#ResponseBody
#RequestMapping(method = { RequestMethod.GET, RequestMethod.POST}, path = "/my/api")
public Mono<String> question() {
return myService.dosomething();
}
I have Spring Security in my class path, this project is a Spring WebFlux Application using 2.6.7 and Java 11.
Upon static analysis scan, I am being flagged with:
Spring CSRF unrestricted RequestMapping
Description
<p>Methods annotated with <code>RequestMapping</code> are by default mapped to all the HTTP request methods.
However, Spring Security's CSRF protection is not enabled by default
for the HTTP request methods <code>GET</code>, <code>HEAD</code>, <code>TRACE</code>, and <code>OPTIONS</code>(as this could cause the tokens to be leaked).
Therefore, state-changing methods annotated with <code>RequestMapping</code> and not narrowing the mapping
to the HTTP request methods <code>POST</code>, <code>PUT</code>, <code>DELETE</code>, or <code>PATCH</code>are vulnerable to CSRF attacks.</p><p> <b>Vulnerable Code:</b><br/><pre><code>#Controller
public class UnsafeController {
...
<b>References</b><br/>Spring Security Official Documentation: Use proper HTTP verbs (CSRF protection)<br/>OWASP: Cross-Site Request Forgery<br/>OWASP: CSRF Prevention Cheat Sheet<br/>CWE-352: Cross-Site Request Forgery (CSRF)</p>
I do not understand this issue.
What I tried:
I tried splitting the Controller onto two different controllers, one for each verb, and for some reason, this fix the issue:
#ResponseBody
#GetMapping(path = "/my/api")
public Mono<String> questionGet() {
return myService.dosomething();
}
#ResponseBody
#PostMapping(path = "/my/api")
public Mono<String> questionPost() {
return myService.dosomething();
}
But I am now carrying a duplicate, therefore, I would like to stay with my:
#ResponseBody
#RequestMapping(method = { RequestMethod.GET, RequestMethod.POST}
I also added Spring Security to protect myself against CSRF, but no luck, the issue still persist.
May I ask what is the proper way to fix this please?
Thank you

Spring Boot Validation with ControllerAdvice Not Behaving Deterministically

I have the following setup
#ControllerAdvice
public class AppControllerAdvice extends ResponseEntityExceptionHandler {
#ExceptionHandler({UserInputValidationException.class})
public ResponseEntity<UserInputValidationResponseBody> handleBadInputException(UserInputValidationException ex, WebRequest request) {
return new ResponseEntity<>(
new UserInputValidationResponseBody().setFieldErrors(ex.getFieldErrors()),
HttpStatus.BAD_REQUEST
);
}
}
This is roughly the #RestController that throws well formatted validation exceptions
#RestController
#RequestMapping("api")
public class MyController {
/**
per the answer, BindingResult must immediately follow the #RequestBody or the item being found
*/
#PostMapping
public ResponseEntity<?> foo(#Valid #RequestBody FormPOJO formBody, Principal principal, BindingResult bindingResult) {
// if bindingResult has errors, throw a UserInputValidationException
}
}
And POJOs that I want to bind have JSR-303 validation annotations on them, Spring correctly validate them at Bind time during request parameter binding
However ... while I got this setup to work for a while - then Spring randomly started to bypass the #RestController and #ControllerAdvice
It appears that now I am receiving org.springframework.web.bind.MethodArgumentNotValidException ... i.e. the request is getting short circuited
I am running Spring Boot 1.5.4.RELEASE ...
EDIT following suggestion from another thread, I added
#Order(Ordered.HIGHEST_PRECEDENCE)
to the controller advice ... it only served to make matters worse. now there is absolutely no validation errors - the client only receives a blank message (which was the symptom of the problem for a while before the current issue surfaced without any code changes)
Ok it turns out
An Errors/BindingResult argument is expected to be declared immediately after the model attribute, the #RequestBody or the #RequestPart arguments to which they apply: public org.springframework.http.ResponseEntity com.remo.api.portfolios.PortfolioController.put(java.security.Principal,org.springframework.validation.BindingResult,com.remo.api.portfolios.Portfolio
tl;dr Please go ahead and make sure #RequestBody is declared IMMEDIATELY before BindingResult

Spring #RepositoryRestController causes #PageableDefault to stop working

I have a custom controller that is using the #PageableDefault annotation. I was using #Controller annotation on my class, however, I wanted to make this controller respond with the HATEOAS response. I added the #RepositoryRestController changed my method to
public HttpEntity<PagedResources<Resource<Books>>> search(#RequestParam(value = "q", required = false) String query, #PageableDefault(page = 0, size = 20) Pageable pageable)
and then the return to
return new ResponseEntity<PagedResources<Resource<Books>>>(booksAssembler.toResource(queryResult), HttpStatus.OK);
Now my #PageableDefault doesn't work. But when a client make a request (e.g. explicitly adding (or without) &page=0&size=20 to the URL) the endpoint from the controller, pageable is always null. I don't get why it stop working after changing the annotation? Is there any way to fix it other than changing back to #Controller?
I found the solution.
I was running into this bug. https://jira.spring.io/browse/DATAREST-906
I was using Spring Boot 1.4.1, upgrading to 1.4.2 solves the problem.

Spring Post: HTTP/1.1 405 Method Not Allowed

I am using spring rest APIs and getting Http 405 error for all the POST methods.
I have following POST method,
#RequestMapping(value = "/GetPlanByBasicContext/", method = RequestMethod.POST)
public #ResponseBody Plan getPlanByBasicContext(#RequestBody BasicPlanContext basicPlanContext)
{
return planService.getPlanByBasicContext(basicPlanContext);
}
I am using fiddler to post the following request,
POST
http://localhost:8080/now/Plan/GetPlanByBasicContext
{ "sourceLocation":"",
"destinationLocation":"",
"modeOfTransport":"car"
"budget":"any"
}
Same attributes are present in BasicPlanContext on the server, along with getters and setters.
I have tried other solutions mentioned and nothing has worked.
Note: Security is not configured for spring yet.
you are posting to a wrong URL , you are missing a trailing slash in the end of your URL, try posting to : http:// localhost:8080/now/Plan/GetPlanByBasicContext/

Spring Web Service Error : 406 Not Acceptable

Here I have written this code for a rest web service in Spring Controllor Class . After build the project I try to use this service using a Restful-Client
RestService Code :-
#RequestMapping(value="/someurl/{prm_passPhraseCode}/{prm_email}", method= RequestMethod.POST)
public #ResponseBody User sendResetLink(#PathVariable("prm_passPhraseCode") String prm_sPassPhrase, #PathVariable("prm_email") String prm_sEmail , HttpServletRequest prm_ObjRequest, HttpServletResponse prm_ObjResponse){
......
..... //some more logical Code.
return new User(); //just dummy object for reference.
}
Here how I tried to access the Url. I have selected the method type as post.
I have also added two headers
Content-Type : application/json
Accept : application/json
URL http://127.0.0.1:8080/webservice.staff.backend/someurl/23812397997713/kumarvikrant625#gmail.com
Although all my other Rest services urls either it is GET or POST are working fine.
I have also try by change the method = RequestMethod.GET but still get the same error.
Error :-
Status Code 406 : The resource identified by this request is only capable of
generating responses with characteristics not acceptable according to the request "accept" headers.
please help if any one have a Idea.
your Url isn't mapped correctly, you are missing sendResetPasswordLink
#RequestMapping(value="/someurl/sendResetPasswordLink/{prm_passPhraseCode}/{prm_email}", method= RequestMethod.POST)
Try this.. May be it can work...
#RequestMapping(value="/someurl/{prm_passPhraseCode}/{prm_email}",headers="Accept=*/*", method= RequestMethod.POST)

Categories