One Drive API returns invalid Access Token - onedrive

The authentication process is not working now.(It was working earlier). By following the documentation I'm trying to get the access token from a refresh token. I successfully can get a access token. But it's not valid. I'm setting it as Bearer and send it in my GET request and it returns the following JSON
{"error":{"code":"accessDenied","message":"Access Denied"}}
Here is the code sample
String messageBody = "client_id=" + "9b1a6dbb-7e1f-41b5-b448-9f328169411e" + "&redirect_uri=" + returnURL + "&client_secret={cleindsecret}
+ "&refresh_token={refreshtoken}&grant_type=refresh_token";
RequestBody oAuthCodeRedeemBody = RequestBody.create(MediaType.parse("application/x-www-form-urlencoded"),
messageBody);
Request request = new Request.Builder().url("https://login.live.com/oauth20_token.srf")
.post(oAuthCodeRedeemBody).build();
String responseBody = null;
OkHttpClient client = new OkHttpClient();
client.setFollowRedirects(false);
Response response;
String accessToken = null;
try {
response = client.newCall(request).execute();
responseBody = response.body().string();
resp = (JSONObject) jsonParser.parse(responseBody);
} catch (IOException | ParseException e) {
e.printStackTrace();
}
accessToken = (String) resp.get("access_token");
I'm getting a Access Token here. But I can't use it to do any work.
Request request2 = new Request.Builder().url("https://api.onedrive.com/v1.0/drive/items/1ED8983F38E94F01!107/children").header("Authorization", "Bearer " + accessToken).get().build();
The response for the above code is returned as
{"error":{"code":"accessDenied","message":"Access Denied"}}
What is the reason here. Is the API returning me a invalid access token or is something wrong in my code?

Related

OkHttp Post Body as JSON is throwing 404

I recently moved into OKHTTP. I'm able to perform get request but while performing post i'm getting 404. Can someone help me out where I'm going wrong.
FYI:
auth token is correct & url is valid
public void PullRequest() throws IOException{
JSONObject jo = new JSONObject();
jo.put("head","patch-7");
jo.put("base","main");
MediaType JSON = MediaType.get("application/json; charset=utf-8");
RequestBody body = RequestBody.create(JSON, jo.toString());
//RequestBody body = RequestBody.create(jo.toString(),JSON);
Request request = new Request.Builder()
.url(url)
.header("Authorization",authorization)
.post(body)
.build();
Call call = httpClient.newCall(request);
Response response = call.execute();
if (response.code()>300) {
System.out.println("error...");
System.out.println(response.body().string());
}else {
System.out.println(response.body().string());
}
}

API test using RestSharp keeps returning 'Unauthorized Access, invalid API key'

I've been trying to figure this out for a couple of days now and that includes looking at similar posted questions but I can't seem to get it to work.
I am trying to post a request to retrieve a Token which I can then use for further API GET requests.
The request I am posting is the below:
[TestMethod]
public void GetToken()
{
var client = new RestClient(baseUrl);
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("Authorization", bearer, ParameterType.HttpHeader);
request.AddParameter("username", username);
request.AddParameter("password", password);
request.AddParameter("api_key", apiKey);
IRestResponse restResponse = client.Execute(request);
Console.WriteLine("Status code: " + (int)restResponse.StatusCode);
Console.WriteLine("Status message " + restResponse.Content);
}
When I run the request, I get the following:
Status code: 200
Status message {"content":null,"error":"Unauthorized Access, invalid API key","success":false}
I cannot figure out why I keep getting the invalid API Key value. In terms of all the variables I use, when I post the request in Postman, it works perfectly fine.
Ok, so I had a look at the code with a developer and turned out I needed to be passing in my apikey as part of the AddParameter value.
So my final code looked like:
[TestMethod]
public void GetToken()
{
var client = new RestClient(baseUrl);
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("Authorization", "Bearer " + apiKey, ParameterType.HttpHeader);
request.AddParameter("username", username);
request.AddParameter("password", password);
IRestResponse restResponse = client.Execute(request);
Console.WriteLine("Status code: " + (int)restResponse.StatusCode);
Console.WriteLine("Status message: " + restResponse.Content);
}

Get missing auditlog from Management Activity API in Office365

Our application calls out-of-the-box Office 365 Management API to retrieve activities and events on files stored in SharePoint Online. However per our experiment, the application can’t seem to retrieve not enough logs.
Example: We upload 1000 files to document library in Sharepoint Online. We receive 8 subscriptiona. Each subscription, we only get maximum 100 logs. Total call API get logs to retrieve 600 logs. Not enough!
Here my code to get subscription
List<SubscriptionsContent> GetSubscriptionsContents(AuthenticationResult authenticationResult, ManagementAPI m, DateTime startDate, DateTime endDate, bool proxyRequired = false)
{
try
{
string jsonSubscription = string.Empty;
string url = string.Empty;
string logType = "Audit.SharePoint";
if (authenticationResult != null)
{
url = string.Format(UrlFormat, m.TenantId, string.Format("subscriptions/content?contentType={0}&startTime={1}&endTime={2}", logType, startDate.ToUniversalTime().ToString(DateFormat), endDate.ToUniversalTime().ToString(DateFormat)));
jsonSubscription = ExecuteRequest(url, HttpMethod.Get, authenticationResult);
//Log.Info("jsonSubscription:");
//Log.Info(jsonSubscription);
}
var listContent = Common.GetListSubscriptionsContent(jsonSubscription);
Log.Info("Common.GetListSubscriptionsContent(jsonSubscription); Count: " + (listContent != null ? listContent.Count.ToString() : "IS NULL"));
return listContent;
}
catch (Exception ex)
{
Log.Error(ex);
return new List<SubscriptionsContent>();
}
}
Here my code to execute Request
public string ExecuteRequest(string url, HttpMethod method, AuthenticationResult token)
{
var responseStr = "";
try
{
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpRequestMessage request = new HttpRequestMessage(method, url);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken);
HttpResponseMessage response = client.SendAsync(request).Result;
Log.Info("ExecuteRequest(string url, HttpMethod method, AuthenticationResult token): response.StatusCode: " + response.StatusCode + " ; response.ReasonPhrase: " + response.ReasonPhrase + " ; response.RequestMessage: " + response.RequestMessage);
if (response.IsSuccessStatusCode)
{
responseStr = response.Content.ReadAsStringAsync().Result;
}
}
catch (Exception ex)
{
Log.Error(ex);
}
return responseStr;
}
Here my code to get audit log from each subscription
List<AuditLog> listAudit = new List<AuditLog>();
foreach (var item in listSubscription)
{
var jsonAudit = ExecuteRequest(item.ContentUri.ToString(), HttpMethod.Get, authenticationResult);
if (string.IsNullOrEmpty(jsonAudit))
continue;
var listAuditLog = Common.GetListAuditLog(jsonAudit);
}
Here my code to parser JsonString
public static List<AuditLog> GetListAuditLog(string jsonString)
{
try
{
return JsonConvert.DeserializeObject<List<AuditLog>>(jsonString);
}
catch (Exception ex)
{
Log.Error("public static List<AuditLog> GetListAuditLog(string jsonString)", ex.InnerException);
return new List<AuditLog>();
}
}
I think that you need to use the pagination header.
If the amount of data is too big, the API will return a header entry named NextPageUrl containing an address to be used to request the next page of results. This link (representing the query) will be available for 24 hours.
Ex.
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
NextPageUrl:https://manage.office.com/api/v1/{tenant_id}/activity/feed/subscriptions/content?contentType=Audit.SharePoint&startTime=2015-10-01&endTime=2015-10-02&nextPage=2015101900R022885001761
So, if the response contains this header entry, just use the value of NextPageUrl to request more data.
Repeat the process until this header entry doesn't exists anymore.
You can find more information in the Office 365 Management API reference

dropbox access token for others to upload to my folder

I plan to have a server program fetching my dropbox account access token and pass to
client program to uplaod to my dropbox folder. Client does not need DB account or login and is able to send file to my DB folder (thus NOT using OAuth ...). Something similar to:
this
and this
but without user upload to server first, i.e., once user get the access token, they upload directly to DB.
I've tried to use Apache httpclient 4.3 to simulate a browser to perform getting request token, sending login-info to get acces token, but get stuck on upload the file via post to a form. Error is HTTP 400 Bad Request ...
executing request:GET https://www.dropbox.com/login HTTP/1.1
----------------------------------------
HTTP/1.1 200 OK
Request Token: moiejtzdLqTA_0sh3gQyNZAI
executing request:POST https://www.dropbox.com/login HTTP/1.1
----------------------------------------
HTTP/1.1 200 OK
Access Token: 5Ot52QKDbDPSsL1ApU4MIapJ
executing request:POST https://dl-web.dropbox.com/upload?
name=sample.jpg&dest=upload&cookie_t=5Ot52QKDbDP....SsJ&t=5Ot5...apJ HTTP/1.1
----------------------------------------
HTTP/1.1 400 Bad Request
I used Firefox LiveHttpHeader to capture the headers as I do the login and upload file, and saw the post to file upload actually is doing this (and reflect in the code):
https://dl-web.dropbox.com/chunked_upload?
name=tmp1.jpg
&chunk=0
&chunks=1
&bjar=W3sic2Vzc1..............Q%253D%253D
&blid=AAAw4tn................2cDxA
&cookie_t=32yq........nw6c34o
&dest=
&t=32yqVof........c34o
&reported_total_size=5611
&upload_id=1BKGRRP5TpCEjcWSu5tmpQ
&offset=0
So apparrently I missed some param but can't figure out what. The access token seems to be valid as I can see my account info in the return from a httpclinet post to https://www.dropbox.com/home, but the upload simply not working. Anyone has similar experience and getting HTTP 400 error ? .... Many Thanks !
Some code as below:
Constructor and main():
// constructor ...
public HttpClientExample() {
gcookies = new BasicCookieStore();
globalConfig = RequestConfig.custom()
.setCookieSpec(CookieSpecs.BEST_MATCH)
.build();
// Create local HTTP context
ghttpContext = HttpClientContext.create();
ghttpContext.setCookieStore(gcookies);
//
redirectStrategy = new LaxRedirectStrategy(); // for http redirect ...
httpclient = HttpClients.custom()
.setDefaultRequestConfig(this.globalConfig)
.setDefaultCookieStore(this.gcookies)
.setRedirectStrategy(redirectStrategy)
.build();
} // constructor ...
public static void main(String[] args) throws Exception {
HttpClientExample myhttp = new HttpClientExample();
try {
this.localConfig = RequestConfig.copy(this.globalConfig)
.setCookieSpec(CookieSpecs.BROWSER_COMPATIBILITY)
.build();
String requestToken = this.getRequestToken(httpclient, loginurl);
theAccessToken = this.postForAccessToken(requestToken, loginurl);
String localFileTopassIn = this.localPath ;
this.postToUpload(httpclient, this.theAccessToken, localFileTopassIn , this.dropboxFolderOnlyName);
}
}
Get the request token:
private String getRequestToken(HttpClient client, String theURL) throws Exception {
HttpGet httpget = new HttpGet(theURL);
httpget.setConfig(localConfig);
httpget.setHeader("Connection", "keep-alive");
System.out.println("\nexecuting request:" + httpget.getRequestLine());
// Create a custom response handler
ResponseHandler responseHandler = new ResponseHandler() {
public String handleResponse(final HttpResponse response)
throws ClientProtocolException, IOException {
int status = response.getStatusLine().getStatusCode();
if (status >= 200 ) { // && status cookies = gcookies.getCookies();
for (Cookie aCookie: cookies) {
String cookieName = aCookie.getName();
if ( !(cookieName.lastIndexOf(gvcString) == -1) ) {
gvc = aCookie.getValue();
} else if ( !(cookieName.lastIndexOf(tString) == -1) ) {
requestToken = aCookie.getValue();
}
}
System.out.println("Request Token: " + requestToken );
return requestToken;
}
postForAccessToken:
private String postForAccessToken(HttpClient client, String requestToken, String theURL) throws Exception{
/*
* Send a post together with request token and my login to get accessToken ...
*/
HttpPost httppost = new HttpPost(theURL); // loginurl);
httppost.setConfig(localConfig);
ghttpContext.setCookieStore(gcookies);
List params = new LinkedList();
params.add(new BasicNameValuePair("login_email", myemail));
params.add(new BasicNameValuePair("login_password", mypasswd));
params.add(new BasicNameValuePair("t", requestToken));
HttpEntity postentity = new UrlEncodedFormEntity(params);
httppost.setEntity(postentity);
System.out.println("\nexecuting request:" + httppost.getRequestLine());
// Create a custom response handler
ResponseHandler responseHandler = new ResponseHandler() {
public String handleResponse(final HttpResponse response)
throws ClientProtocolException, IOException {
int status = response.getStatusLine().getStatusCode();
if (status >= 200 ) { // && status cookies = gcookies.getCookies();
for (Cookie aCookie: cookies) {
String cookieName = aCookie.getName();
if ( !(cookieName.lastIndexOf(tString) == -1) ) {
theAccessToken = aCookie.getValue();
}
}
System.out.println("Access Token: " + theAccessToken );
return theAccessToken;
}
postToUpload:
private String postToUpload(HttpClient client, String accessToken, String localFileInfo, String destPath) throws Exception{
String bjarString = "bjar";
String blidString = "blid";
String bjar=null;
String blid=null;
List cookies = gcookies.getCookies();
for (Cookie aCookie: cookies) {
String cookieName = aCookie.getName();
if ( !(cookieName.lastIndexOf(bjarString) == -1) ) {
bjar = aCookie.getValue();
} else if ( !(cookieName.lastIndexOf(blidString) == -1) ) {
blid = aCookie.getValue();
}
}
String[] fileNameArry = localFileInfo.split("(\\\\|/)");
String filename = fileNameArry[fileNameArry.length - 1]; // get the last part ...
URI uri = new URIBuilder()
.setScheme("https")
.setHost("dl-web.dropbox.com")
.setPath("/upload")
.setParameter("name", filename)
.setParameter("dest", destPath)
.setParameter("cookie_t", accessToken)
.setParameter("t", accessToken)
.build();
HttpPost httppost = new HttpPost(uri);
httppost.setConfig(localConfig);
ghttpContext.setCookieStore(gcookies);
FileBody bin = new FileBody(new File(localFileInfo));
StringBody comment = new StringBody("A binary file of some kind", ContentType.DEFAULT_BINARY);
HttpEntity reqEntity = MultipartEntityBuilder.create()
.addPart("bin", bin)
.addPart("comment", comment)
.build();
httppost.setEntity(reqEntity);
// add header
httppost.setHeader("Host", "www.dropbox.com");
httppost.setHeader("User-Agent", USER_AGENT);
httppost.setHeader("Accept",
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
httppost.setHeader("Connection", "keep-alive");
httppost.setHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
httppost.setHeader("Pragma", "no-cache");
httppost.setHeader("Cache-Control", "no-cache");
// add entity
System.out.println("\nexecuting request:" + httppost.getRequestLine());
// Create a custom response handler
ResponseHandler responseHandler = new ResponseHandler() {
public String handleResponse(final HttpResponse response)
throws ClientProtocolException, IOException {
int status = response.getStatusLine().getStatusCode();
if (status >= 200 ) { // && status
OAuth is the only way to use the Dropbox API. Once you have an OAuth access token (which you get by authenticating once, in this case with your account), you just need to do an HTTP PUT to https://api-content.dropbox.com/1/files_put/auto/<path> with the header Authorization: Bearer <token> and the contents of the file in the body.
Note that anyone who has your access token can also delete all your files, upload their personal DVD collection, etc. So it's not recommended that you share that access token.
There is files_get_temporary_upload_link:
Get a one-time use temporary upload link to upload a file to a Dropbox location.
This endpoint acts as a delayed upload. The returned temporary upload link may be used to make a POST request with the data to be uploaded. The upload will then be perfomed with the CommitInfo previously provided to get_temporary_upload_link but evaluated only upon consumption. Hence, errors stemming from invalid CommitInfo with respect to the state of the user's Dropbox will only be communicated at consumption time. Additionally, these errors are surfaced as generic HTTP 409 Conflict responses, potentially hiding issue details. The maximum temporary upload link duration is 4 hours. Upon consumption or expiration, a new link will have to be generated. Multiple links may exist for a specific upload path at any given time.
So you need to have an access token to call this function, but the uploader needs only the produced URL, without access to the rest of the Dropbox vault.

Eventbrite OAUTH2 login on windows store apps keep me get BAD REQUEST

I got problem on oauth2 handshake, as the eventbrite documentation is not very clear.
http://developer.eventbrite.com/doc/authentication/oauth2/ -> number 4
what i currently do is like this
WebRequest webRequest = WebRequest.Create("https://www.eventbrite.com/oauth/token");
string URLEncoded = "code=" + token + "&client_secret=" + APISecret + "&client_id=" + APIKey + "&grant_type=authorization_code";
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Method = "POST";
byte[] bytes = Encoding.UTF8.GetBytes(URLEncoded);
Stream os = null;
try
{
os = await webRequest.GetRequestStreamAsync();
os.Write(bytes, 0, bytes.Length);
WebResponse response = await webRequest.GetResponseAsync();
os = response.GetResponseStream();
StreamReader reader = new StreamReader(os);
string responseFromServer = reader.ReadToEnd();
}
catch (WebException ex)
{
string err = ex.ToString();
}
finally
{
if (os != null)
{
os.Dispose();
}
}
Can someone give tips on this? i keep getting BAD REQUEST as a result. Thank you
edited : the response say : code is invalid or expired
I know its clear, but i already implement and get the token to exchange, use Secret API key and API Key to get it, but how come its invalid/expired?