Getting access token for SharePoint through http request via proxy server - rest

I am able to get access token for SharePoint from accounts.accesscontrol.windows.net while I am running my application on a machine which is allowed to connect to external URL.
But when I am running my application on an environment where I can only go via a proxy server, its giving me 401: Permission denied (connect failed) even through I have added the proxy code. I am given a ProxyServer URL and port; its of type http.
Please find my code for direct hit below. This is working absolutely fine in open env:
private String getToken(String tenant_id,String client_id, String client_secret, String domain)
{
String resultToken=null;
try {
// AccessToken url
String wsURL = "https://accounts.accesscontrol.windows.net/"+ tenant_id+"/tokens/OAuth/2";
URL url = new URL(wsURL);
URLConnection connection = url.openConnection();
HttpURLConnection httpConn = (HttpURLConnection) connection;
// Set header
httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
httpConn.setRequestMethod("POST");
String jsonParam = "grant_type=client_credentials"
+ "&client_id="+client_id+"#"+tenant_id
+ "&client_secret="+client_secret
+ "&resource=00000003-0000-0ff1-ce00-000000000000/" +domain+".com#"+tenant_id;
System.out.println("TokenRequestString : " + jsonParam);
// Send Request
DataOutputStream wr = new DataOutputStream(httpConn.getOutputStream());
wr.writeBytes(jsonParam);
wr.flush();
wr.close();
// Read the response.
InputStreamReader isr = null;
if (httpConn.getResponseCode() == 200) {
isr = new InputStreamReader(httpConn.getInputStream());
} else {
isr = new InputStreamReader(httpConn.getErrorStream());
}
BufferedReader in = new BufferedReader(isr);
String responseString = "";
String outputString = "";
// Write response to a String.
while ((responseString = in.readLine()) != null) {
outputString = outputString + responseString;
}
// Extracting accessToken from string, here response
// (outputString)is a Json format string
if (outputString.indexOf("access_token\":\"") > -1) {
int i1 = outputString.indexOf("access_token\":\"");
String str1 = outputString.substring(i1 + 15);
int i2 = str1.indexOf("\"}");
String str2 = str1.substring(0, i2);
accessToken = str2;
}
} catch (Exception e) {
accessToken = "Error: " + e.getMessage();
}
return accessToken;
}
Below is my code where I am trying to achieve the same thing through proxy server. This is throwing Permission Denied (401)
private String getToken(String tenant_id,String client_id, String client_secret, String domain)
{
String resultToken=null;
try {
// AccessToken url
String wsURL = "https://accounts.accesscontrol.windows.net/"+ tenant_id+"/tokens/OAuth/2";
URL url = new URL(wsURL);
// via Proxy
Proxy webProxy
= new Proxy(Proxy.Type.HTTP, new InetSocketAddress("internet.xyz.com", 83);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(webProxy);
// Set header
httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
httpConn.setRequestMethod("POST");
String jsonParam = "grant_type=client_credentials"
+ "&client_id="+client_id+"#"+tenant_id
+ "&client_secret="+client_secret
+ "&resource=00000003-0000-0ff1-ce00-000000000000/" +domain+".com#"+tenant_id;
System.out.println("TokenRequestString : " + jsonParam);
// Send Request
DataOutputStream wr = new DataOutputStream(httpConn.getOutputStream());
wr.writeBytes(jsonParam);
wr.flush();
wr.close();
// Read the response.
InputStreamReader isr = null;
if (httpConn.getResponseCode() == 200) {
isr = new InputStreamReader(httpConn.getInputStream());
} else {
isr = new InputStreamReader(httpConn.getErrorStream());
}
BufferedReader in = new BufferedReader(isr);
String responseString = "";
String outputString = "";
// Write response to a String.
while ((responseString = in.readLine()) != null) {
outputString = outputString + responseString;
}
// Extracting accessToken from string, here response
// (outputString)is a Json format string
if (outputString.indexOf("access_token\":\"") > -1) {
int i1 = outputString.indexOf("access_token\":\"");
String str1 = outputString.substring(i1 + 15);
int i2 = str1.indexOf("\"}");
String str2 = str1.substring(0, i2);
accessToken = str2;
}
} catch (Exception e) {
accessToken = "Error: " + e.getMessage();
}
return accessToken;
}

Related

Unable to get token from tableau server

I am following below link to integrate tableau report on web application(asp .net mvc),
https://onlinehelp.tableau.com/current/server/en-us/trusted_auth.htm
https://onlinehelp.tableau.com/current/server/en-us/trusted_auth_webrequ.htm
Code :
var uri = "http://<server ip>:8000/trusted";
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters.Add("username ", "<user>");
parameters.Add("target_site", "<site>");
var bodyParameters = new ArrayList();
foreach (var parameter in parameters)
{
bodyParameters.Add(string.Format("{0}={1}", HttpUtility.UrlEncode(parameter.Key), HttpUtility.UrlEncode(Convert.ToString(parameter.Value))));
}
string requestBody = String.Join("&", bodyParameters.ToArray());
var request = WebRequest.CreateHttp(uri);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
try
{
using (var writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(requestBody);
}
var response = (HttpWebResponse)request.GetResponse();
using (var reader = new StreamReader(response.GetResponseStream()))
{
String body = reader.ReadToEnd();
}
}
catch (Exception ex)
{
string str = ex.Message.ToString();
}
My machine is registered as trusted host on tableau server, still i am getting -1 when i request for token.

400 Bad Request when posting to Rest API over https

I'm trying to post a file in a json object to an external rest api over https. I have confirmed the json object is formatted correctly, do I have to do anything special to post to a rest api over https? I'm using the answer found over here as a guide: How to post JSON to the server?
private static void PostDatatoFTP(string FileName,
string fileString, string centerCode, string fileType) {
try {
byte[] plainTextBytes = Encoding.ASCII.GetBytes(fileString);
string base64File = Convert.ToBase64String(plainTextBytes);
FileInfo fileInfo = new FileInfo {
FileData = base64File,
FileName = FileName,
FileType = fileType,
FileVersion = _fileVersion
};
FileInfo[] transmitFileInfo = new FileInfo[1];
transmitFileInfo[0] = fileInfo;
Json jsonObject = new Json {
RequestType = _RequestType,
APIVersion = _apiVersion,
SubmissionId = Guid.NewGuid().ToString(),
UserId = _ftpUsername,
Password = _ftpPassword,
Vendor = _vendor,
CenterCode = centerCode,
FileInfo = transmitFileInfo
};
var json = JsonConvert.SerializeObject(jsonObject);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_uploadPath);
request.Method = "POST";
request.ContentType = "application/json";
using (var streamWriter = new StreamWriter(request.GetRequestStream())) {
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream() ?? throw new InvalidOperationException())) {
var result = streamReader.ReadToEnd();
Console.WriteLine(result);
}
}
catch (WebException e) {
Console.WriteLine(e.Message);
String status = ((HttpWebResponse)e.Response).StatusDescription;
Console.WriteLine(status);
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
}
}

Google API Batch Request - .NET REST Call Gives error

I am having .NET code to call the google api in batch request for getting the message details for multiple Ids. The request I am creating, when run through postman it works perfectly but when run this console app it gives me the Response Status code = 0 and Error Specified value has invalid CRLF characters.\r\nParameter name: value
Can someone please look into this and help me ... I have searched almost everything now but could not get any solution.
Here is my code --
var baseUrl = "/gmail/v1/users/" + _accountID + "/messages/";
RestClient client = null;
RestRequest request = null;
StringBuilder sbBody = null;
for (int j = 0; j < _messageId.Count; j++)
{
msgCount++;
if (msgCount == 1)
{
boundary = "testing_batch";
sbBody = new StringBuilder();
client = new RestClient("https://www.googleapis.com/batch/");
request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "multipart/mixed; boundary=\"" + boundary + "\"");
request.AddHeader("Authorization", "Bearer " + accessToken);
}
sbBody.Append(string.Format("--{0}\n", boundary));
sbBody.Append("Content-Type: application/http\n\n");
sbBody.Append(string.Format("GET {0}{1}\n\n", baseUrl, _messageId[j]));
if (msgCount == 1)
sbBody.Append(string.Format("--{0}--", boundary));
if (msgCount == 1)
{
msgCount = 0;
//request.AddBody(sbBody.ToString());
request.AddHeader("RequestBody", sbBody.ToString());
IRestResponse response = client.Execute(request);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
//Do nothing for now
}
else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
{
Console.WriteLine(response.StatusCode);
Console.WriteLine(response.Content);
Console.ReadLine();
break;
}
else
{
Console.WriteLine(response.StatusCode);
Console.WriteLine(response.Content);
Console.ReadLine();
break;
}
}

Azure Storage Service throws 403 forbidden error when trying to call REST API to clear queue messages

I'm trying to clear all azure storage queue message via Queue Service REST API. I've verified that the code is correct, but it still returns a 403 forbidden error. The "StorageSharedKey" and "StorageAccountName" are correct since I'm able to connect to the azure queue using those values in the connection string for the azure queue client. The storage version I'm using is "2015-12-11".
Here is the code:
internal void ClearStorageQueueMessages(string queueName)
{
const string requestMethod = "DELETE";
string urlPath = $"{queueName}/messages";
var dateInRfc1123Format = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
var canonicalizedHeaders = $"x-ms-date:{dateInRfc1123Format}\nx-ms-version:{StorageVersion}";
var canonicalizedResource = $"/{StorageAccountName}/{urlPath}";
var uri = new Uri($"https://{StorageAccountName}.queue.core.windows.net/{urlPath}");
var response = MakeDeleteRestCall(uri, requestMethod, dateInRfc1123Format, canonicalizedHeaders, canonicalizedResource);
}
internal RestResponse MakeDeleteRestCall(Uri uri, string requestMethod, string dateInRfc1123Format, string canonicalizedHeaders,
string canonicalizedResource)
{
var restResponse = new RestResponse();
var stringToSign = $"{requestMethod}\n\n\n\n\n\n\n\n\n\n\n\n{canonicalizedHeaders}\n{canonicalizedResource}";
var authorizationHeader = CreateAuthorizationHeader(stringToSign);
var request = (HttpWebRequest) WebRequest.Create(uri);
request.Method = requestMethod;
request.Headers.Add("x-ms-date", dateInRfc1123Format);
request.Headers.Add("x-ms-version", StorageVersion);
request.Headers.Add("Authorization", authorizationHeader);
//request.Accept = "application/atom+xml,application/xml";
request.Accept = "application/json";
//request.ContentType = "application/json";
using (var response = (HttpWebResponse) request.GetResponse())
{
restResponse.StatusCode = response.StatusCode;
var responseStream = response.GetResponseStream();
if (responseStream == null)
return restResponse;
using (var reader = new StreamReader(responseStream))
{
restResponse.ReturnedContent = reader.ReadToEnd();
}
}
return restResponse;
}
internal static string CreateAuthorizationHeader(string canonicalizedString)
{
string signature;
using (var hmacSha256 = new HMACSHA256(Convert.FromBase64String(StorageSharedKey)))
{
var dataToHmac = Encoding.UTF8.GetBytes(canonicalizedString);
signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
}
var authorizationHeader = string.Format(CultureInfo.InvariantCulture, "{0} {1}:{2}", StorageSharedKey,
StorageAccountName, signature);
return authorizationHeader;
}
The problem seems to be with the header Authorization. Please check the format according to the documentation:
Authorization="[SharedKey|SharedKeyLite] :"
https://msdn.microsoft.com/en-us/library/azure/dd179428.aspx
Your function adds the shared key in plain text instead of the authorization scheme "SharedKey" or "SharedKeyLite".

(OAuthException - #200) (#200) The user hasn't authorized the application to perform this action

I'm trying out the facebook api. I'm getting this error that i'm not authorized to perform this action. I have accepted all the pop-ups that came when i run the program. Anyone got a quick soulution for this?
sing Facebook;
public void CheckAutorization()
{
string app_Id = "xxxxxxxxxxxxxxx";
string app_secret = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy";
string scope = "publish_stream, manage_pages";
if (Request["code"] == null)
{
Response.Redirect(string.Format(
"https://graph.facebook.com/oauth/authorize?client_id={0}&redirect_uri={1}&scope={2}",
app_Id, Request.Url.AbsoluteUri, scope));
}
else
{
Dictionary<string, string> tokens = new Dictionary<string, string>();
string url = string.Format("https://graph.facebook.com/oauth/access_token?client_id={0}&redirect_uri={1}&scope={2}&code={3}&client_secret={4}",
app_Id, Request.Url.AbsoluteUri, scope, Request["code"].ToString(), app_secret);
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
StreamReader reader = new StreamReader(response.GetResponseStream());
string vals = reader.ReadToEnd();
foreach (string token in vals.Split('&'))
{
//meh.aspx?token1=steve&token2=jake&...
tokens.Add(token.Substring(0, token.IndexOf("=")),
token.Substring(token.IndexOf("=") + 1, token.Length - token.IndexOf("=") - 1));
}
}
string access_token = tokens["access_token"];
var client = new FacebookClient(access_token);
client.Post("/me/feed", new { message = "Is there anyone out there? :) Can i get a whoop whoop" });
}
}
}
}
Had to change the scope string scope = "publish_stream, manage_pages" to string scope = "publish_stream, publish_actions";