I am trying to build a console app that reads the data from SharePoint list.
But i dont want to pass the user credentials in order to authenticate, instead use the token. Is this possible?
I tried using the following code but i get forbidden error while trying to GetFormDigest
static void Main(string[] args)
{
string sConnStr = "https://sab/sites/DevT";
Uri oUri = null;
oUri = new Uri(sConnStr + "/_api/web/lists/getbytitle('sd')/GetItems");
string sResult = string.Empty;
string stringData = "{'query' : {'__metadata': { 'type': 'SP.CamlQuery' }, 'ViewXml':'<View><Query><Where><Eq><FieldRef Name =\"Title\"/><Value Type=\"Text\">HR</Value></Eq></Where></Query></View>'}}";
HttpWebRequest oWebRequest = (HttpWebRequest)WebRequest.Create(oUri);
oWebRequest.Credentials = CredentialCache.DefaultNetworkCredentials;
oWebRequest.Method = "POST";
oWebRequest.Accept = "application/json;odata=verbose";
oWebRequest.ContentType = "application/json;odata=verbose";
oWebRequest.Headers.Add("X-RequestDigest", GetFormDigest());
oWebRequest.ContentLength = stringData.Length;
StreamWriter writer = new StreamWriter(oWebRequest.GetRequestStream());
writer.Write(stringData);
writer.Flush();
WebResponse wresp = oWebRequest.GetResponse();
using (StreamReader sr = new StreamReader(wresp.GetResponseStream()))
{
sResult = sr.ReadToEnd();
}
}
public static string GetFormDigest()
{
string sFormDigest = null;
string sConnStr = "https://sab/sites/DevT";
Uri oUri = null;
oUri = new Uri(sConnStr + "/_api/contextinfo");
HttpWebRequest oWebRequest = HttpWebRequest.Create(oUri) as HttpWebRequest;
oWebRequest.UseDefaultCredentials = true;
oWebRequest.Method = "POST";
oWebRequest.Accept = "application/json;odata=verbose";
oWebRequest.ContentLength = 0;
oWebRequest.ContentType = "application/json";
string sResult;
WebResponse sWebReponse = oWebRequest.GetResponse();
using (StreamReader sr = new StreamReader(sWebReponse.GetResponseStream()))
{
sResult = sr.ReadToEnd();
}
var jss = new JavaScriptSerializer();
var val = jss.Deserialize<Dictionary<string, object>>(sResult);
var d = val["d"] as Dictionary<string, object>;
var wi = d["GetContextWebInformation"] as Dictionary<string, object>;
sFormDigest = wi["FormDigestValue"].ToString();
return sFormDigest;
}
You could use Add-in authentication to access SharePoint data.
You could check my test demo below.
https://social.msdn.microsoft.com/Forums/office/en-US/d33f5818-f112-42fb-becf-3cf14ac5f940/app-only-token-issue-unauthorized-access?forum=appsforsharepoint
Related
I am trying to get the FormDigest from SharePoint online. I am using credentials which are working when I login to SharePoint site. However, when I connect to SharePoint via C#, it gives *
The remote server returned an error: (401) Unauthorized.
error.
Below is the code for the same.
public static string GetFormDigest()
{
string formDigest = null;
try
{
const string RESTURL = "{0}/_api/contextinfo";
string restUrl = string.Format(RESTURL, sharepointUrl);
HttpWebRequest wreq = HttpWebRequest.Create(restUrl) as HttpWebRequest;
var securePassword = new SecureString();
//Convert string to secure string
foreach (char c in password)
securePassword.AppendChar(c);
securePassword.MakeReadOnly();
var creds = new SharePointOnlineCredentials(username, securePassword);
wreq.Credentials = creds;
wreq.Method = "POST";
wreq.Accept = "application/json;odata=verbose";
wreq.ContentLength = 0;
wreq.ContentType = "application/json";
wreq.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
wreq.UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)";
WebResponse wresp = wreq.GetResponse();
string result;
using (StreamReader sr = new StreamReader(wresp.GetResponseStream()))
{
result = sr.ReadToEnd();
}
var jss = new JavaScriptSerializer();
var val = jss.Deserialize<Dictionary<string, object>>(result);
var d = val["d"] as Dictionary<string, object>;
var wi = d["GetContextWebInformation"] as Dictionary<string, object>;
formDigest = wi["FormDigestValue"].ToString();
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
return formDigest;
}
METHOD #2
using (var clientContext = new ClientContext("<<SharePointURL>>"))
{
var securedPassword = GetSecuredPassword();
// SharePoint Online Credentials
clientContext.Credentials = new SharePointOnlineCredentials(username, securedPassword);
// Get the SharePoint web
Web web = clientContext.Web;
// Load the Web properties
clientContext.Load(web);
// Execute the query to the server.
clientContext.ExecuteQuery();
// Web properties - Display the Title and URL for the web
Console.WriteLine("Title: " + web.Title + "; URL: " + web.Url);
Console.ReadLine();
}
METHOD #3
public static async void GetDigest()
{
try
{
const string RESTURL = "{0}/_api/contextinfo";
string restUrl = string.Format(RESTURL, sharepointUrl);
var uri = new Uri(restUrl);
var credentialsCache = new CredentialCache
{{uri, "NTLM", new NetworkCredential(username, password, domain)}};
var handler = new HttpClientHandler {Credentials = credentialsCache};
var httpClient = new HttpClient(handler) {BaseAddress = uri};
httpClient.DefaultRequestHeaders.ConnectionClose = false;
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "text/xml");
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("DataServiceVersion", "3.0");
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Host", "helenoy.sharepoint.com");
ServicePointManager.FindServicePoint(uri).ConnectionLeaseTimeout =
120 * 1000; // Close connection after two minutes
var response = httpClient.PostAsync(uri, null).Result;
string respdata = await response.Content.ReadAsStringAsync();
Console.WriteLine(respdata);
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace + ex.Message);
}
}
I am trying to make a post request to yobit api in UWP platform,this codes are working for other platforms.Here are my codes-
public async Task<RootObject> sellLimitCode()
{
RootObject track = null;
try
{
string url = "https://yobit.net/tapi/";
string parameters = "method=Trade&pair=ltc_btc&type=buy&rate=1&amount=1&nonce=" + (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
String strMsg = "api secret";
var uriBytes = encoding.GetBytes(parameters);
var uriBytes1 = encoding.GetBytes(strMsg);
string str_alg_name = MacAlgorithmNames.HmacSha512;
MacAlgorithmProvider obj_mac_prov = MacAlgorithmProvider.OpenAlgorithm(str_alg_name);
IBuffer buff_msg = CryptographicBuffer.CreateFromByteArray(uriBytes);
IBuffer buff_key_material = CryptographicBuffer.CreateFromByteArray(uriBytes1);
CryptographicKey hmac_key = obj_mac_prov.CreateKey(buff_key_material);
IBuffer hmac = CryptographicEngine.Sign(hmac_key, buff_msg);
byte[] digest = hmac.ToArray();
string hashText = byteToString(digest);
StringBuilder hex1 = new StringBuilder(hashText.Length * 2);
foreach (byte b in digest)
{
hex1.AppendFormat("{0:x2}", b);
}
string sign1 = hex1.ToString();
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.Method = "POST";
httpWebRequest.Headers["Key"] = "api key";
httpWebRequest.Headers["Sign"] = sign1;
httpWebRequest.ContentType = "application/x-www-form-urlencoded";
var httpResponse = (HttpWebResponse)await httpWebRequest.GetResponseAsync();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
}
catch (Exception ex)
{ }
return track;
}
But I am getting Success:0,invalid key,method or nonce.I have tried changing everything.Still not working.
I am doing post and get response using HttpClient to communicate with REST API as below:
public static string PostToAPI( string value)
{
var payload = new APIModel
{
CommandText = value
};
var stringPayload = JsonConvert.SerializeObject(payload);
var httpContent = new StringContent(stringPayload,Encoding.UTF8,"application/json");
System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
HttpResponseMessage message=client.PostAsync("https://testAPI/test",httpContent).Result if (message.IsSuccessStatusCode)
{
string result = message.Content.ReadAsStringAsync().Result;
return result;
}
return string.Empty;
}
is there any other alternative or best way do it?
You can always use HttpWebRequest and HttpWebResponse. Try Below
try
{
var webAddr = "URL";
var httpWebRequest = (HttpWebRequest)WebRequest.Create(webAddr);
httpWebRequest.ContentType = "application";
httpWebRequest.Method = "POST";
string str = "request string";
httpWebRequest.Headers["Authorization"] = "";
httpWebRequest.Headers["TenantId"] = "";
httpWebRequest.Headers["Client-Type"] = "";
httpWebRequest.Headers["Protocol"] = "";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
Console.WriteLine(str);
streamWriter.Write(str);
streamWriter.Flush();
streamWriter.Close();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
Console.WriteLine("result=" + result);
}
}
catch (WebException ex)
{
Console.WriteLine(ex.Message);
}
HttpResponse response;
request.AllowAutoRedirect = false;
request.UserAgent = HttpHelper.IEUserAgent();
response = request.Post("https://www.site.com", "value=1");
But after request, program trys to open file value=1. Why?
Try this option, code:
using (var request = new HttpRequest())
{
request.UserAgent = HttpHelper.RandomUserAgent();
request.Proxy = Socks5ProxyClient.Parse("127.0.0.1:1080");
var reqParams = new StringDictionary();
reqParams["login"] = "neo";
reqParams["password"] = "knockknock";
string content = request.Post(
"www.whitehouse.gov", reqParams).ToText();
string secretsGovernment = content.Substring("secrets_government=\"", "\"");
}
And read documentation here
Post(string address, string path) - send file. You can set the parameters as:
1:
using (var request = new HttpRequest())
{
var reqParams = new RequestParams();
reqParams["login"] = "neo";
reqParams["password"] = "knockknock";
string content = request.Post(
"www.whitehouse.gov", reqParams).ToString();
}
2:
using (var request = new HttpRequest("www.whitehouse.gov"))
{
request
.AddParam("login", "neo")
.AddParam("password", "knockknock");
string content = request.Post("/").ToString();
}
3:
using (var request = new HttpRequest())
{
var reqParams = new Dictionary<string, string>()
{
{"login", "neo"},
{"password", "knockknock"},
};
var httpContent = new FormUrlEncodedContent(reqParams);
string content = request.Post(
"www.whitehouse.gov", httpContent).ToString();
}
4:
using (var request = new HttpRequest())
{
string reqStr = "param1=value1¶m2=value2";
string content = request.Post(
"www.whitehouse.gov", reqStr,
"application/x-www-form-urlencoded").ToString();
}
I am tring to pull categories from my store on BigCommerce via API.
When I try my credentials at API Console;
https://developer.bigcommerce.com/console
it is working fine, but I when send credentials via C# post request it does not work.
I am receiving [{"status":401,"message":"No credentials were supplied in the request."}]
My code is like;
List<PostCredential> postCredentials = new List<PostCredential>();
postCredentials.Add(new PostCredential { name = "store_url", value = ApiPath });
postCredentials.Add(new PostCredential { name = "username", value = Username });
postCredentials.Add(new PostCredential { name = "api_key", value = ApiToken });
JavaScriptSerializer serializer = new JavaScriptSerializer();
string serialize = serializer.Serialize(postCredentials);
const string requestUrl = "https://myteststore1234.mybigcommerce.com/api/v2/categories.json";
StringBuilder postData = new StringBuilder();
postData.Append(serialize);
string postRequest = PostRequest(requestUrl, postData.ToString());
public static string PostRequest(string url, string postData)
{
HttpWebRequest httpWReq = (HttpWebRequest)WebRequest.Create(url);
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] data = encoding.GetBytes(postData);
httpWReq.Method = "POST";
httpWReq.ContentType = "application/x-www-form-urlencoded";
httpWReq.ContentLength = data.Length;
using (Stream stream = httpWReq.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
HttpWebResponse response = (HttpWebResponse)httpWReq.GetResponse();
Stream responseStream = response.GetResponseStream();
if (responseStream != null)
{
string responseString = new StreamReader(responseStream).ReadToEnd();
return responseString;
}
return null;
}
is there any workaround for this?
WebHeaderCollection wHeader = new WebHeaderCollection();
wHeader.Clear();
//wHeader.Add("username:test");
//wHeader.Add("password:4afe2a8a38fbd29c32e8fcd26dc51f6d9b5ab99b");
//wHeader.Add("u","test:4afe2a8a38fbd29c32e8fcd26dc51f6d9b5ab99b");
string Username = "test";
string ApiToken = "4afe2a8a38fbd29c32e8fcd26dc51f6d9b5ab99b";
string sUrl = "https://store-bwvr466.mybigcommerce.com/api/v2/brands.json"; //txtstoreurl.Text.ToString() + "/api/v2/products.json";
HttpWebRequest wRequest = (HttpWebRequest)System.Net.HttpWebRequest.Create(sUrl);
wRequest.Credentials = new NetworkCredential(Username, ApiToken);
wRequest.ContentType = "application/json"; //' I don't know what your content type is
//wRequest.Headers = wHeader;
wRequest.Method = "GET";
HttpWebResponse wResponse = (HttpWebResponse)wRequest.GetResponse();
string sResponse = "";
using (StreamReader srRead = new StreamReader(wResponse.GetResponseStream()))
{
sResponse = srRead.ReadToEnd();
MessageBox.Show(sResponse);
}
After some research I found out I need to pass parameters like this;
httpWReq.Method = "GET";
httpWReq.ContentType = "application/json";
httpWReq.ContentLength = data.Length;
httpWReq.Credentials = new NetworkCredential(Username, ApiToken);