Response and response body for other than 201 status codes not found - azure-ad-graph-api

I'm trying to fetch the error response from the graph api while creating the user on AD but not able to capture the response from the api for other than 201 which is a user created successfully.
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(new MediaType[] { MediaType.APPLICATION_JSON }));
headers.set("Authorization", "Bearer " + token);
headers.set("Content-Type", "application/json");
try{
HttpEntity<String> request = new HttpEntity<String>(jsonRequest.toString(), headers);
responseEntity = restTemplate.postForEntity(graphUrl, request, String.class);
}catch(Exception e){
System.out.println("Result - status ("+ responseEntity.getStatusCode() + ") has body: " + responseEntity.hasBody());
}
Whenever the response is other than 201 it show me an exception Bad Request 400
I'm getting a error response with postman but with same payload the response is null in Java app

Spring's RestTemplate and Spring Boot's TestRestTemplate will on JDK's internal HttpURLConnection implementation by default, which fails to access the body of an HTTP-response with status 401 "Unauthorized". You could use HTTPClient which doesn't face the problem.
You could refer to the following workgroup:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version> <scope>test</scope>
</dependency>
String token="eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Im5iQ3dXMTF3M1hrQi14VWFYd0tSU0xqTUhHUSIsImtpZCI6Im5iQ3dXMTF3M1hrQi14VWFYd0tSU0xqTUhHUSJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuYXp1cmUuY29tLyIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0L2U0YzlhYjRlLWJkMjctNDBkNS04NDU5LTIzMGJhMmE3NTdmYi8iLCJpYXQiOjE1NDY1NzkxNTgsIm5iZiI6MTU0NjU3OTE1OCwiZXhwIjoxNTQ2NTgzMDU4LCJhaW8iOiI0MlJnWU5qSG45NTBZV0p5dXIvZXozL0trNm9iQUE9PSIsImFwcGlkIjoiNjNkMzk0ZDctYjA1OC00MDRkLWJjYjMtMThmODhmN2UzY2FhIiwiYXBwaWRhY3IiOiIxIiwiaWRwIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvZTRjOWFiNGUtYmQyNy00MGQ1LTg0NTktMjMwYmEyYTc1N2ZiLyIsIm9pZCI6ImZiZmVkNzhiLWNkYWUtNDU3NC05YzM4LTY0MjlmMjI2MTMyOCIsInN1YiI6ImZiZmVkNzhiLWNkYWUtNDU3NC05YzM4LTY0MjlmMjI2MTMyOCIsInRpZCI6ImU0YzlhYjRlLWJkMjctNDBkNS04NDU5LTIzMGJhMmE3NTdmYiIsInV0aSI6IlVTRzMzM3B3Q2tDc3MxN3ZRdVFDQUEiLCJ2ZXIiOiIxLjAifQ.cFfptQOBt_BQKAbOSFsewmAMsgku15G8oKrfTuxD8ID2AZYtIWqEt1kFXKYBb66Hmsephe_KgyyeByIY_RLPW7JT3cpMTiSkh1DsiRvdAJJkZ0fcmgWQsZB-mmsS-Kt5vTUO1F5EtNeneaaklexfuEMG9E_hUiPKM2v46LlD3pO9ZPlq45157nUMcxPJlPpeHoE3riXwBEUQTCUFTm60NHOG1Cs_NuC_bVHBC3oN-pCFabz-vMo4O2Zikxn6S-BYxz909EP5lAmRNjKgH3uPYHS5rWfve20NiUPy8nOyBHKgz6XxAJXz7PVxm_hTOtdsGC9Hg8bdxnOKctPo95vAlQ";
String jsonRequest="{\"test\":\"a\"}";
String graphUrl="https://graph.microsoft.com/v1.0/users";
HttpClient client = new HttpClient();
PostMethod postMethod = new PostMethod(graphUrl);
postMethod.setRequestHeader("Content-Type", "application/json");
postMethod.setRequestHeader("Authorization", "Bearer " + token);
postMethod.setRequestBody(jsonRequest);
try {
int code = client.executeMethod(postMethod);
String res = postMethod.getResponseBodyAsString();
System.out.print(res);
} catch (IOException e) {
e.printStackTrace();
}
And you could refer to other information here.

StringEntity postStr = new StringEntity(jsonRequest);
CloseableHttpClient client = HttpClients.createDefault();
HttpPost postM = new HttpPost(graphUrl);
postM.setHeader("Content-Type", "application/json");
postM.setHeader("Authorization", "Bearer " +token);
postM.setEntity(postStr);
try {
CloseableHttpResponse response = client.execute(postMethod);
int statusCode = response.getStatusLine().getStatusCode();
if(statusCode == 201){
String res = EntityUtils.toString(response.getEntity());
}
The code above worked for me.

Related

How to make a POST request with multiple headers and a raw text body in Spring Boot REST?

The body is in raw text format and the request is a POST method. I am using this code.
#RequestMapping(value = "/run", method = RequestMethod.POST)
ResponseEntity<String> runReport(){
RestTemplate restTemplate = new RestTemplate();
String fooResourceUrl = "requestURL";
String auth = "username:password";
byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes(Charset.forName("US-ASCII")) );
String authHeader = "Basic " + new String( encodedAuth );
// Defining the Headers
MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
headers.add("Authorization", authHeader);
headers.add("Content-Type", "multipart/form-data; boundary=\"Boundary_1_1153447573_1465550731355\"");
headers.add("Accept", "multipart/form-data");
// Defining the Body
String outputFormatType = "pdf";
String body = "--Boundary_1_1153447573_1465550731355\n"
+"Content-Type: application/json\n"
+"Content-Disposition: form-data;" + " "+"name=\"ReportRequest\"\n\n"
+"{\"byPassCache\":true,\"flattenXML\":false,\"attributeFormat\":"+ "\""+outputFormatType+"\"" +"}\n"
+"--Boundary_1_1153447573_1465550731355--";
HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
restTemplate.getInterceptors().add(new BasicAuthorizationInterceptor("username", "password"));
ResponseEntity<String> result = restTemplate.exchange(fooResourceUrl, HttpMethod.POST, entity, String.class);
return result;
}
It was solved by removing the following line:
restTemplate.getInterceptors().add(new BasicAuthorizationInterceptor("username", "password"));
As it was already being added in header. And added the body as a parameter to the HttpEntity constructor:
HttpEntity<String> entity = new HttpEntity<>(body, headers);

Unable to access REST API’s in Camunda

In our project , we are trying to use camunda BPMN. using camunda standalone distro and deployed and running in Tomcat.
login as a admin user and able to access cockpit and task lists.But,when we try access the APIs using a Java client . we are getting an unauthorized (401) error. Though we are sending JSESSIONID as a “Cookie”
Tried both DefaultHttpClient and HttpURLConnection - It didn’t work out
Note : JSESSIONID is retrieved by calling the login api with admin username and password.
Help me to solve the issue
Attached below is the java client code
public static void main(String[] args) {
CamundaBMPNClient bpmnClient = new CamundaBMPNClient();
Map<Integer, String> cookieHeader = bpmnClient.getCookieHeader();
bpmnClient.getListofTasks(cookieHeader);
}
public Map<Integer, String> getCookieHeader() {
String jSessionID = null;
Map<Integer, String> headerValues = new HashMap<Integer, String>();
HttpClient httpClient = HttpClientBuilder.create().build();
HttpPost request = new HttpPost(
"http://localhost:8090/camunda-webapp-tomcat-standalone-7.2.0/"
+ "api/admin/auth/user/default/login/cockpit");
request.addHeader("content-type", "application/x-www-form-urlencoded");
request.addHeader("Accept", "application/json");
String jsonString = new Gson()
.toJson("username=admin&password=admin#123");
StringEntity params;
try {
params = new StringEntity(jsonString);
request.setEntity(params);
HttpResponse response = httpClient.execute(request);
Header[] cookieheader = response.getHeaders("Set-Cookie");
for (Header s : cookieheader) {
// Do your stuff here
System.out.println(s.getValue());
String[] str = s.getValue().split(";");
int i = 1;
for (String s1 : str) {
headerValues.put(i, s1.trim());
i++;
}
}
System.out.println("jSessionID::" + jSessionID);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return headerValues;
}
public void getListofTasks(Map<Integer, String> cookieHeader) {
int id = 0;
// DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost request = new HttpPost(
"http://localhost:8090/camunda-webapp-tomcat-standalone-7.2.0/api/engine/engine/default/task");
request.addHeader("Content-type", "application/json");
String[] arrJSessionID = cookieHeader.get(1).split("=");
System.out.println("" + arrJSessionID[1]);
CookieStore cookieStore = new BasicCookieStore();
BasicClientCookie cookie = new BasicClientCookie("JSESSIONID=",
arrJSessionID[1]);
cookie.setDomain("http://localhost:8090");
cookie.setPath("/camunda-webapp-tomcat-standalone-7.2.0/");
// cookie.setAttribute(ClientCookie.DOMAIN_ATTR, "true");
cookieStore.addCookie(cookie);
// httpclient.setCookieStore(cookieStore);
HttpClient httpclient = HttpClientBuilder.create()
.setDefaultCookieStore(cookieStore).build();
String jsonString = new Gson().toJson("{}");
StringEntity jsonStr;
try {
jsonStr = new StringEntity(jsonString);
request.setEntity(jsonStr);
HttpResponse response = httpclient.execute(request);
int statusCode = response.getStatusLine().getStatusCode();
Header[] header = response.getHeaders("Set-Cookie");
for (Header h : header) {
System.out.println(h.getValue());
}
System.out.println("statusCode::" + statusCode);
} catch (Exception e) {
e.printStackTrace();
}
}

CORS error while Rest API return 401

I have REST API in Spring as Backend and Angular 2 as Frontend.
I call login URL. When response is 201 all its fine, but when I send 401 / 403 I have an error.
XMLHttpRequest cannot load http://localhost:8888/emot/login. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 401.
Before i had this error in all request so I changed my call method in Client :
authenticate(login: string, password: string) {
let headers = this.createBasicHeaders();
this.createAuthorizationHeader(headers, login, password);
const options = new RequestOptions({headers: headers});
console.log(this.http.post(this.restApi + "/emot/login", '{}', options)
.map(this.extractData)
.toPromise()
.catch(this.handleError));
}
createAuthorizationHeader(headers: Headers, login: string, password: string) {
headers.append('Authorization', 'Basic ' +
btoa(login + ':' + password));
}
createBasicHeaders(): Headers {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
// Website you wish to allow to connect
headers.append('Access-Control-Allow-Origin', this.restApi);
// Request methods you wish to allow
headers.append('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
headers.append('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
headers.append('Access-Control-Allow-Credentials', 'true');
return headers;
}
private extractData(res: Response) {
const body = res.json();
console.log("GOOD");
return body.data || {};
}
private handleError(error: Response | any) {
let errMsg: string;
if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
}
else {
errMsg = error.message ? error.message : error.toString();
}
return Observable.throw(errMsg);
}
My Server Controller :
#RestController
#ComponentScan("xxxx")
#RequestMapping("/xxx")
#CrossOrigin(origins = "*")
public class RootRequestDispatcher {
#Autowired
OperatorFacade operatorFacade;
#RequestMapping(value = "login", method = RequestMethod.POST)
public ResponseEntity<OperatorDTO> logon(Authentication auth) {
System.out.println(auth);
OperatorDTO operator = operatorFacade.findOperatorByLogin(auth.getName());
return new ResponseEntity<OperatorDTO>(operator, HttpStatus.OK);
}
}
And the response sended when Operator Cretentials are NOT OK :
#Override
public void commence(HttpServletRequest request,
HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.addHeader(SecurityProperties.HEADER_NAME_REALM, SecurityProperties.HEADER_VALUE_REALM + getRealmName());
authException.printStackTrace();
System.out.println("TESTING ERROR");
ObjectMapper mapper = new ObjectMapper();
PrintWriter writer = response.getWriter();
writer.println(mapper.writeValueAsString(new ExceptionBean(Causes.ANOTHER_CAUSE)));
}
I found myself solution.
For this problem, it is needed to override AccessDeniedHandler bean. And not like I did it in previous post.
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
#Override
public void handle(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
AccessDeniedException e) throws IOException,
ServletException {
httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
httpServletResponse.addHeader(SecurityPathProperties.HEADER_NAME_REALM,
SecurityPathProperties.HEADER_VALUE_REALM + SecurityPathProperties.REALM);
ObjectMapper mapper = new ObjectMapper();
PrintWriter writer = httpServletResponse.getWriter();
writer.println(mapper.writeValueAsString(new ExceptionBean(ExceptionCauses.NOT_FOUND_USER)));
}
}

How to add new account in Quickbooks

Below is the code I am using to try to add a new account to QuickBooks online. I am getting a (400) Bad Request. Can anyone help me with this.
HttpWebRequest httpWebRequest =
WebRequest.Create("https://sandbox-quickbooks.api.intuit.com/v3/company/xxxxxxxxxxx/account")
as HttpWebRequest;
httpWebRequest.Method = "POST";
httpWebRequest.Headers.Add("Authorization", GetDevDefinedOAuthHeader(httpWebRequest, ConsumerKeyQb, ConsumerSecQb, AccessKey, AccessSec));
httpWebRequest.ContentType = "application/json";
httpWebRequest.Accept = "application/xml";
string json = "{\"AccountType\":\"Accounts Receivable\",\"Name\":\"MySampleAccount\"}";
byte[] bytes = Encoding.UTF8.GetBytes(json);
httpWebRequest.ContentLength = bytes.Length;
using (Stream putStream = httpWebRequest.GetRequestStream())
{
putStream.Write(bytes, 0, bytes.Length);
}
HttpWebResponse httpWebResponse = null;
try
{
httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse;
}
catch (Exception e)
{
//return null;
var x = "Stop";
}
Thanks
400 response suggests that your API request payload is not correct.
You can try this call using IPP provided .net devkit.
https://developer.intuit.com/docs/0025_quickbooksapi/0055_devkits/0150_ipp_.net_devkit_3.0/0002_synchronous_calls/0001_data_service_apis
Using Dev-defined lib( sample call ) -
https://gist.github.com/IntuitDeveloperRelations/0913b4c224de758fde0a
Thanks

Get body of Bad Request httpURLConnection.getInputStream()

I've been working on a portlet that calls Rest API. When the API is called and the requested data doesn't exist, it returns an appropriate error message in JSON format (with Bad request http code - 400), and if the id exists, it returns the requested data in json (with code 200).
How can I get the body of response (that contains error description) because invoking httpConn.getInputStream() method throws exception in case the response is bad request error.
Code:
HttpURLConnection httpConn = null;
URL url = new URL("http://192.168.1.20/personinfo.html?id=30");
URLConnection connection = url.openConnection();
httpConn = (HttpURLConnection) connection;
httpConn.setRequestProperty("Accept", "application/json");
httpConn.setRequestMethod("GET");
httpConn.setRequestProperty("charset", "utf-8");
BufferedReader br = null;
if (!(httpConn.getResponseCode() == 400)) {
br = new BufferedReader(new InputStreamReader((httpConn.getInputStream())));
String output;
StringBuilder builder = new StringBuilder();
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null)
builder.append(output);
return builder.toString();
}else
here should catch the error message. :)
In case of non-successful response codes, you have to read the body with HttpURLConnection.getErrorStream().
you can get body of Bad Request in HttpURLConnection using this code :
InputStream errorstream = connection.getErrorStream();
String response = "";
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(errorstream));
while ((line = br.readLine()) != null) {
response += line;
}
Log.d("body of Bad Request HttpURLConnection", "Response: " + response);
Use Apache Httpclient:
String url = "http://192.168.1.6:7003/life/lifews/getFirstInstallment.html?rootPolicyNo=1392/2126/2/106/9995/1904&token=1984";
HttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet(url);
// add request header
HttpResponse response = client.execute(request);
System.out.println("Response Code : " + response.getStatusLine().getStatusCode());
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null)
result.append(line);
System.out.println(result);