The best way for handle JWT SignatureException - spring-boot

When client sends an invalid token to my server, the server will return 500 status code. I think that is ugly. Wouldn't 400 (bad request) code be more correct?
If 400 code is more correct then how to handle 500 error? I tried to catch SignatureException and throw ResponseStatusException but then I receive a response like this:
{
"timestamp": "2020-10-17T09:34:26.939+00:00",
"status": 500,
"error": "Internal Server Error",
"message": "400 BAD_REQUEST \"cause: token is invalid\"",
"path": "/toucan/user/delete"
}
My specified message and status code are in message in error with code 500. Is there a way to throw 400 status without 500?

First, let's talk about the status code.
If the token sent is invalid, then the user is not authorized to use API which is 401 status code.
Then let's talk about how to intercept your exception in Spring. You should check the official documentation and either use #ResponseStatus(value=HttpStatus.UNAUTHORIZED, reason="Invalid Token") on SignatureException class (or catch it and throw a custom Exception with the annotation).
Either implement a #ControllerAdvice to handle exceptions through methods with the following annotation : #ExceptionHandler(value = SignatureException.class).
Both solutions are mentionned in the documentation.

Related

How to return 401 ("Unauthorized") from AWS Lambda Authorizer

We are using AWS Lambda Authorizer with API Gateway to protect our downstream API's.
Below is the code snippet from our Java based lambda authorizer
Statement statement = Statement.builder()
.resource(input.getMethodArn()).effect(effect)
.build();
PolicyDocument policyDocument = PolicyDocument.builder()
.statements(
Collections.singletonList(statement)
).build();
return AuthorizerResponse.builder()
.principalId(userId)
.policyDocument(policyDocument)
.context(ctx)
.build();
With correct token (effect = "Allow"): getting proper API response from API
With incorrect token (effect = "Deny") Getting 403 HTTP response code.
We need 401 ("Unauthorized") as a response, Can someone pls help how to do this ? we have lambda authorizer written in java.
You can throw RuntimeException with Unauthorized message. One thing is to be in mind, you can not throw checked exception like Exception("Unauthorized"). Because handleRequest method signature of RequestHandler interface don't allow to do so.
if(isInvalidToken){
throw new RuntimeException("Unauthorized");
}
Try throwing an exception with a message of "Unauthorized".

How to solve error message "status": 415, "error": "Unsupported Media Type"," for DELETE request in Spring?

I created a Spring Boot application based on Service Components using this tutorial.
My delette request is constructed in the following way:
#RequestMapping(value = "/api/greetings/{id}", method = RequestMethod.DELETE, consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Greeting> deleteGreeting(#PathVariable("id") Long id, #RequestBody Greeting greeting) {
greetingService.delete(id);
return new ResponseEntity<Greeting>(HttpStatus.NO_CONTENT);
}
All the other requests work finally, but if I make the DELETE request in Postman I get the following error:
{
"timestamp": 1519060345434,
"status": 415,
"error": "Unsupported Media Type",
"exception": "org.springframework.web.HttpMediaTypeNotSupportedException",
"message": "Content type 'application/x-www-form-urlencoded' not supported",
"path": "/api/greetings/2"
}
I have checked the following issues, nothing helped (which is no wonder, none of them is issuing the DELETE request:
415 Unsupported MediaType
415 Unsupported MediaType for POST request in spring application
415 Unsupported Media Type in RESTful webservice
Ask
Your controller is expecting application/json as content-type but as the error message displays
"message": "Content type 'application/x-www-form-urlencoded' not supported",
you should change the header in postman to content-type application/json

How can I insert an interceptor with AngularJS to redirect to login page?

I have a login system that will hold the session for 2 hours. After 2 hours, when the client makes API calls, they get back an error:
{
"Success": false,
"Error": {
"ErrorCode": "002",
"ErrorMessage": "Session expired"
}
}
I need to then redirect the client to /login when that happens. The problem is that I get that error from individual API calls, so rather than change EVERY API call, is it possible to have a global interceptor?
Following the example for Interceptors found here, you can do something like the following in the response section of the interceptor:
response: function(resp){
// resp.data will contain your response object from the server
if(resp.data && !resp.data.Success){
// check for error code
if(resp.data.Error && resp.data.ErrorCode === '002'){
$location.path('/login');
return $q.reject(resp);
}
}
return resp || $q.when(resp);
},
This is assuming that your server is returning a 200 when you get this error message, not on a 401 or 403, but that's what it looks like you're doing. Hope that helps.

Change response code in AbstractHttpMessageConverter

Is it possible to change the response status code in a AbstractHttpMessageConverter writeInternal() method?
In my AbstractHttpMessageConverter (extending MappingJackson2HttpMessageConverter) I want to change error responses to 200 and add the actual status code (e.g. 400) to a status field in the json.
EDIT1
I'm returning code like:
JSONObject json= new JSONObject();
json.put("name", "My Name");
return new ResponseEntity<JSONObject>(json, HttpStatus.OK);
or in case of an error:
JSONObject json= new JSONObject();
json.put("error", "My Error");
return new ResponseEntity<JSONObject>(json, HttpStatus.BAD_REQUEST);
Somewhere I want to intercept the response body and:
a) wrap the original response body (enity) with status code
b) change response status code to 200
So for both variants this would mean:
{ "status": 200, "response": { "name": "My Name" } }
{ "status": 400, "response": { "error": "My Error" } }
and in both case a http status 200 will be returned.
I was thinking of doing this by extending the MappingJackson2HttpMessageConverter and overiding the writeInternal method, but unfortunately there I cannot change the status code.
Note I don NOT want to this in my controller classes. They should just return the base json structure.
No, it is not possible. The HttpMessageConverter can set certain headers and write the body of a message, but it cannot set the status code. Perhaps you can change the status code to 200 and set a property to 400 before sending the object to the HttpMessageConverter.
I like to use the ResponseEntity object, which allows you to set a status code along with an object, but without seeing your code, I don't know if it will work for you.

Status of ajax or post request

status - contains the status of the request like
("success", "notmodified", "error", "timeout", or "parsererror") /ajax or post
I know what is success,not modified,error meant here but I am unable to find out how to handle this errors. If the call back is success then update my div, if there is any error not modified, error, time out, parse error then let me alert a pop up some error occurred.
What would be the cause for each type of error? I mean the situations where not modified,timeout,error and parseerror occurs.
If it results success, then does it mean my post request has successfully worked?
My local-server xampp never results any error, the status is always success. I guess, since its limited to my system but when I put my website online there exists several issues like traffic on server.
So how do I find out, whether my post request to some sample.php page was successfully sent and else pop out an alert to user if something went wrong?
The error types are a little self-explanatory. They simply provide a string for you to easily handle the different errors.
error callback option is invoked, if the request fails. It receives the jqXHR, a string indicating the error type, and an exception object if applicable. Some built-in errors will provide a string as the exception object: "abort", "timeout", "No Transport".
Source: jQuery.Ajax documentation
Codes Explained:
Error: Any of the HTTP response codes, like the well-know 404 (not found) or other internal server errors.
Notmodified: Compares the cached version of the browser with the server's version. If they are the same, the server responds with a 304
Timeout: Ajax requests are time-limited, so errors can be caught and handled to provide a better user experience. Request timeouts are usually either left at their default or set as a global default using $.ajaxSetup() rather than being overridden for specific requests with the timeout option.
Parse Error: The jQuery data (JSON) cannot be parsed (usually due to syntax errors)
Handling these error codes:
Here is some example of handling the errors
$(function() {
$.ajaxSetup({
error: function(jqXHR, exception) {
if (jqXHR.status === 0) {
alert('Not connect.\n Verify Network.');
} else if (jqXHR.status == 404) {
alert('Requested page not found. [404]');
} else if (jqXHR.status == 500) {
alert('Internal Server Error [500].');
} else if (exception === 'parsererror') {
alert('Requested JSON parse failed.');
} else if (exception === 'timeout') {
alert('Time out error.');
} else if (exception === 'abort') {
alert('Ajax request aborted.');
} else {
alert('Uncaught Error.\n' + jqXHR.responseText);
}
}
});
});
Source: Blog Post - jQuery Error Handling
Success
Response code is between 200-299 or is 304 Not Modified.
Not Modified
Response code is 304. If you employ caching, the browser can tell the server which version it currently has, and the server compares this with its version and if there has been no change, it can send a 304 Not Modified response, to indicate to the client that their version is up to date. In jQuery ajax, a 304 Not Modified response will still fire the success handler.
Error
Response code is between 400-599. This could be for example 404 not found, 403 forbidden, 500 internal server error etc.
Parse Error
This is a jQuery internal, not actually a HTTP response. This will happen if jQuery is trying to parse JSON or XML that is not in the valid format or has syntax errors.
Timeout
Again, this isn't a HTTP response. The ajax request has a timeout which if is exceeded before the server responds, will abort the request.
If you control the server side, in your example a PHP script, and you never change the response code using header() then your ajax will always receive 200 OK responses unless there is an unhandled exception in the PHP which will trigger a 500 internal server error.
It is acceptable to always send 200 OK response codes. For example, if the server outputs a JSON object which contains its own success/error flag then any errors can be handled by looking at the flag.
As far as I know
not modified: Server sends a Not Modified(304) response status
timeout: the server has not responded within the time period specified by the timeout property
error: server response with a error status like 4xx or 5xx
parseerror: there was an client side error when processing server response like an invalid json format/xml format

Resources