What defines jqXHR as "failed" - ajax

I have a ajax request to a spring security backend. What happens for some reason is that .then doesn't occur ever. What I found out is that .fail occurs on every request, even though the request goes through, the login on the backend works and it returns a response with status code 200. So what defines a jqXHR as failed and what do I need to add in the response so it works as it should?
Here is my ajax request:
// Creates request object
function makeRequest(method, module, endpoint) {
return req = {
method,
url: serverBaseUrl + module + '/' + endpoint
};
}
// Function to return POST promise
function post (module, endpoint, data) {
let req = makeRequest('POST', module, endpoint);
req.data = data;
return $.ajax(req);
}
And here is the response I get from my spring security setup:
HTTP/1.1 200
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 0
Date: Wed, 28 Mar 2018 01:02:20 GMT
Expires: 0
Pragma: no-cache
Set-Cookie: JSESSIONID=8D6265E912D5DFCF418238F18586AFE1; Path=/; HttpOnly
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block

After all my problem was in my $.ajax request. I had a dataType parameter added as application/json. That seems to be not valid. Found it out when i printed the error from the request when it failed. Got the answer from here:
jquery ajax call return JSON parsing error

Related

Using Postman and Soapui I get a 400 when hitting a Spring Boot endpoint, but Swagger has no problem

The endpoint is in a RestController with this signature:
#PostMapping(value = "/unclaim")
#Operation(summary = "Unclaim Tasks ")
public BaseResponse<String> claimTasks(
#RequestParam(required = true, name = "taskIds") Long taskIds[]
)
{
If I use Soap ui to the correct URL ( I know I got that right, b/c if I append another character to it, I get a 404 ) I send this payload:
{
taskIds: [ 444, 34, 55 ]
}
Doing this in SoapUI and Postman both give 400s and no explanation :
HTTP/1.1 400
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Set-Cookie: JSESSIONID=C18701F799961FEECF967457574EB914; Path=/tlmapi; HttpOnly
Content-Length: 0
Date: Fri, 02 Sep 2022 16:11:44 GMT
Connection: close
But going to the swagger-ui.html page for this controller lets me construct a request that works :
So what's the difference ? Or is there a way to see the payload that swagger is sending?
Turns out that I accidentally was using the #RequestParam annotation on the list, instead of #RequestBody. Further, the param was Required, so spring rejected it and ignored my Json payload from SoapUI and Postman.
Hope this helps someone not waste a couple of hours...

Springboot Mockito : Mocked service method returning empty body

I have the following jersey controller.
#POST
#ApiOperation(value = "", response = Certification.class)
public Response addCertification(#Valid CertificationRequest request) {
return Response.ok(certificationService.addCertification(request)).build();
}
I have then developed the following test using Mockito and SpringRunner.
#Test
public void givenValidToken_whenAddingCertification_thenCorrect() {
CertificationRequest certificationRequest = new CertificationRequest();
certificationRequest.setName("name");
Certification certification = new Certification();
when(certificationService.addCertification(certificationRequest)).thenReturn(certification);
given()
.contentType(ContentType.JSON)
.body(certificationRequest)
.when()
.post("/certifications")
.then()
.assertThat()
.statusCode(200)
.contentType(ContentType.JSON)
.log()
.all();
}
Written just like that, I receive the following error when it is executed.
HTTP/1.1 200
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 0
Date: Fri, 26 Jun 2020 18:33:35 GMT
java.lang.AssertionError: 1 expectation failed.
Expected content-type "JSON" doesn't match actual content-type "".
On the other hand, if I add null in place of certificationRequest and send an empty body in RestAssured , it works fine.
Why does it return an empty body when sent with a request body ?
At least one of your problems is the following:
when(certificationService.addCertification(certificationRequest)).thenReturn(certification);
You need a Matcher instead of certificationRequest. If you want to match any Request you can use ArgumentMatchers.any(). If you want to check for a specific Request you can use ArgumentMatchers.eq(certificationRequest). Note that ArgumentMatchers.eq(...) will only work if you've provided a valid equals method (Or if you pass exactly the same argument, afair).
So for example:
when(certificationService.addCertification(ArgumentMatchers.eq(certificationRequest))).thenReturn(certification);
If that doesn't solve your problem, I would try to print the response and check what you get there.

rxjs5 Observable.ajax ignores explicitly set HTTP headers

I'm getting my feet wet with redux-observable and OAuth2 authentication. I'm stuck at the point where I have to POST adding Authorization header to my HTTP request. The header is has not been added. Instead, I see any custom-set header names as values of Access-Control-Request-Headers, and that's it.
This is a redux-observable 'epic':
const epicAuth = function(action$){
return action$.ofType(DO_AUTHENTICATE)
.mergeMap(
action => Rx.Observable.ajax( authRequest(action.username, action.password))
.map( response => renewTokens(response))
.catch(error => Rx.Observable.of({
type: AJAX_ERROR,
payload: error,
error: true,
}))
)
}
This is my request object:
const authRequest = function(username, password){
return {
url: TOKEN_PROVIDER + '?grant_type=password&username=' + username + '&password=' + password,
method: 'POST',
responseType: 'json',
crossDomain: true,
withCredentials: true,
headers: {
'Authorization': 'Basic <base64-encoded-user#password>',
}
}
}
The HTTP headers captured:
http://localhost:8082/api/oauth/token?grant_type=password&username=xxx&password=yyy
OPTIONS /api/oauth/token?grant_type=password&username=xxx&password=yyy HTTP/1.1
Host: localhost:8082
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:56.0) Gecko/20100101 Firefox/56.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Access-Control-Request-Method: POST
Access-Control-Request-Headers: authorization
Origin: http://localhost:3000
DNT: 1
Connection: keep-alive
HTTP/1.1 401
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
WWW-Authenticate: Basic realm="MY_REALM/client"
Content-Type: text/html;charset=utf-8
Content-Language: en
Content-Length: 1098
Date: Wed, 01 Nov 2017 17:57:38 GMT
It all ends up with 401 response, since the Authorization header was not sent. I have tested the Oauth2 endpoint manually with Postman tool, and all went well: I've got a valid access token, could renew it, etc. CORS is enabled on server side.
What am I missing here?
The client code is working correctly.
You've captured the OPTIONS cors request, which is asking the server if it is OK to POST the Authorization header (see the Access-Control-Request-Headers: authorization).
Make sure that you've configured CORS correctly on your server. It shouldn't be trying to authenticate OPTIONS calls. It should instead be sending a proper response which tells the browser if it is allowed to make the POST call.

rest assured sprint security login

I am trying to test my app using rest assured, I am using spring security
This is sthe code
RestAssured.baseURI = "http://myapp-breakid.rhcloud.com/";
RestAssured.port = 80;
Response response = expect().given().auth().form("admin", "sababa1.",springSecurity().withLoggingEnabled(new LogConfig())).
when().get("login");
but this is the response:
HTTP/1.1 302 Found
Date: Mon, 01 Dec 2014 20:38:57 GMT
Server: Apache-Coyote/1.1
Location: http://myapp-breakid.rhcloud.com/index
Content-Length: 0
Set-Cookie: JSESSIONID=32E5F577A6885826DF17ACEE4B3386AF; Path=/; HttpOnly
Accept-Ranges: none
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/plain
What am I missing ?
You don't need to go to the login page to login, REST Assured does this automatically. This works:
RestAssured.baseURI = "http://myapp-breakid.rhcloud.com";
RestAssured.authentication = form("admin", "sababa1.", springSecurity());
get("/index").prettyPrint();
What happens here is that form authentication is automatically performed before each request. If it's important to use the same session in multiple requests you should use a session filter. For example:
RestAssured.baseURI = "http://myapp-breakid.rhcloud.com";
SessionFilter sessionFilter = new SessionFilter();
given().
auth().form("admin", "sababa1.", springSecurity()).
filter(sessionFilter).
when().
get("/index");
// Session filter will automatically capture the session id and you can reuse it in subsequent requests.
given().
filter(sessionFilter).
when().
get("/another_protected_resource").
then().
statusCode(200);
You can also get the sessionId from the SessionFilter and use it like this:
given().
sessionId(sessionFilter.getSessionId()).
when().
get("/another_protected_resource").
then().
statusCode(200);

Google OAuth 2: response_type error on token request

I am trying to return an OAuth 2 response code for an OAuth response token. However, my request returns the following error which has zero results in google. I tried changing response_type to "token" instead of "code" but that didn't work either.
OAuth 2 parameters can only have a single value: response_type
Request Details:
scope=https://www.googleapis.com/auth/userinfo.email
client_secret=_____
response_type=code
grant_type=authorization_code
redirect_uri=http://localhost/folder/
client_id=____.apps.googleusercontent.com
code=_____
I'm sending this second-step payload to POST https://accounts.google.com/o/oauth2/auth
What is wrong with my request?
Edit
I just realized that there is the https://accounts.google.com/o/oauth2/token URL that should be used for this request. However, changing to that URL now gives:
HTTP/1.0 400 Bad Request
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: Fri, 01 Jan 1990 00:00:00 GMT
Date: Fri, 27 Jul 2012 22:44:35 GMT
Content-Type: application/json
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Server: GSE
{
"error" : "invalid_request"
}
Edit 2
Removing the response_type and changing the URL like above solved this.
After receiving the authorization code you have to ask '/o/oauth2/token' for the access token. This request takes no 'scope' and no 'response_type' parameters. See the Google documentation for more details.
After trying out a couple of methods, the required parameters to make the OAUTH2 call are
redirect_uri, response_type, scope, client_id. I kept on debugging the oauth call based on the error report I received.

Resources