I have read and read and played with this code inside out and I still cant work out how to get the refresh token. This in c#
I have tried different combo of access_type, prompt and approval_prompt params.
I keep revoking access by my user to the app, so when the auth code is being requested it does ask for myself to approve the app to be able to access.
I just want to get the refresh token so i can store it and keep refreshing.
here is the code below. I have removed the parts to get the auth code, but if it is needed i can add in. I wonder if anyone can simply spot something simply wrong.
string GetJsonFromAPICall(string p_url,string p_post_data, string p_b64_id_secret)
{
//string C_TOKEN_URL = "https://oauth2.googleapis.com/token";
string l_auth_string = "Basic " + p_b64_id_secret;
print("p_post_data = ", p_url + "?"+p_post_data);
print("Authorization", l_auth_string);
HttpWebRequest request = WebRequest.Create(p_url) as HttpWebRequest;
string postData = p_post_data;// "grant_type=authorization_code&code=" + p_auth_code + "&redirect_uri=" + p_redirect_url;
request.Headers.Add("Authorization", l_auth_string);
var data = Encoding.ASCII.GetBytes(postData);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
print("pos 20 in GetJsonFromAPICall");
print("length ", data.Length.ToString());
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
return responseString;
}
string getAccessToken(string p_b64_id_secret, string p_auth_code, string p_redirect_url)
{
//string l_url = "client_id="+ p_C_GBQ_ONLINE_APP_APP_CLIENT_ID + "&client_secret="+ p_C_GBQ_ONLINE_APP_APP_CLIENT_SECRET + "access_type=offline&prompt=consent&grant_type=authorization_code&code=" + p_auth_code + "&redirect_uri=" + p_redirect_url;
string l_params = "grant_type=authorization_code&code=" + p_auth_code + "&redirect_uri=" + p_redirect_url;
l_params += "&access_type=offline";
l_params += "&prompt=consent";
l_params += "&approval_prompt=force";
//return GetJsonFromAPICall("https://oauth2.googleapis.com/token", l_params, p_b64_id_secret);
return GetJsonFromAPICall("https://www.googleapis.com/oauth2/v4/token", l_params, p_b64_id_secret);
}
var credentials = string.Format("{0}:{1}", C_GBQ_ONLINE_APP_APP_CLIENT_ID, C_GBQ_ONLINE_APP_APP_CLIENT_SECRET_ID);
var b64_id_secret = Convert.ToBase64String(Encoding.UTF8.GetBytes(credentials));
string l_auth_code = "xxxxx"; // worked out successfully earlier
l_json_returned = getAccessToken(p_b64_id_secret, l_auth_code, C_GBQ_ONLINE_APP_REDIRECT_URL);
the returned json is
l_json_returned = : {
"access_token": "FFFFFFFF",
"expires_in": 3569,
"scope": "https://www.googleapis.com/auth/cloud-platform.read-only https://www.googleapis.com/auth/bigquery",
"token_type": "Bearer"
}
Related
Context
I am developing a simple application that requires to receive List Data from a company Online SharePoint site. In order to make REST requests, I must first retrieve an access token from Microsoft's access control service. Despite attempting some tutorials and reading documentation, I am new to REST/HTTP am am failing to do so.
What have I tried?
Used SharePoint appregnew.aspx to register my app, and generate "Client ID" and "Client Secret" values. https://[sitename].sharepoint.com/_layouts/15/appregnew.aspx
Used Sharepoint appinv.aspx to authorize my app with read control and generate a "Tenant ID".
https://[sitename].sharepoint.com/_layouts/15/appinv.aspx
<AppPermissionRequests AllowAppOnlyPolicy="true">
<AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web" Right="Read"/>
</AppPermissionRequests>
Used SharePoint AppPrincipals.aspx to verify Tenant ID. https://[sitename].sharepoint.com/_layouts/15/AppPrincipals.aspx
Attempted several methods of formatting the request with the following being the latest:
Updated
// Variables removed for security
class Program
{
static void Main(string[] args)
{
WebRequest myWebRequest;
string stGetAccessTokenUrl = "https://accounts.accesscontrol.windows.net/{0}/tokens/OAuth/2";
string tenantID = "myTenantID";
string resourceID = "00000003-0000-0ff1-ce00-000000000000";
string stClientID = "myClientID";
string stClientSecret = "myClientSecret";
string stSiteDomain = "[myCompany].sharepoint.com";
// URL Format
stGetAccessTokenUrl = string.Format(stGetAccessTokenUrl, tenantID);
myWebRequest = WebRequest.Create(stGetAccessTokenUrl);
myWebRequest.ContentType = "application/x-www-form-urlencoded";
myWebRequest.Method = "POST";
// Add the below body attributes to the request
var postData = "grant_type=client_credentials";
postData += "&client_id=" + stClientID + "#" + tenantID;
postData += "&client_secret=" + stClientSecret;
postData += "&resource=" + resourceID + "/" + stSiteDomain + "#" + tenantID;
var data = Encoding.ASCII.GetBytes(postData);
using (var stream = myWebRequest.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)myWebRequest.GetResponse();
}
}
What doesn't work?
I receive a 401 Unauthorized error despite the app having been assigned permissions.
Any help would be greatly appreciated!
Apologies, I forgot to return to this question upon resolving the issue. Credit to "Michael Han" within the comments of his own answer.
Answer
By default, the SharePoint app-only permissions is disabled for the tenant. A tenant administrator must first run the following cmdlet in PowerShell:
Set-SPOTenant -DisableCustomAppAuthentication $false
This parameter supersedes all other privilege settings and must first be configured.
You could refer to this article to get the access token : https://social.technet.microsoft.com/wiki/contents/articles/51982.sharepoint-read-online-list-data-from-c-console-application-using-access-token.aspx
#region Get Access Token using TenantID and App secret ID & Password
// URL Format
//https://accounts.accesscontrol.windows.net/tenant_ID/tokens/OAuth/2 Jump
stGetAccessTokenUrl = string.Format(stGetAccessTokenUrl, tenantID);
myWebRequest = WebRequest.Create(stGetAccessTokenUrl);
myWebRequest.ContentType = "application/x-www-form-urlencoded";
myWebRequest.Method = "POST";
// Add the below body attributes to the request
/*
* grant_type client_credentials client_credentials
client_id ClientID#TenantID
client_secret ClientSecret
resource resource/SiteDomain#TenantID resourceid/abc.sharepoint.com#tenantID
*/
var postData = "grant_type=client_credentials";
postData += "&client_id=" + stClientID +"#" +tenantID;
postData += "&client_secret=" + stClientSecret;
postData += "&resource=" + resourceID + "/" + stSiteDomain + "#" + tenantID;
var data = Encoding.ASCII.GetBytes(postData);
using (var stream = myWebRequest.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)myWebRequest.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
string[] stArrResponse = responseString.Split(',');
//get the access token and expiry time ,etc
foreach(var stValues in stArrResponse)
{
if(stValues.StartsWith("\"access_token\":"))
{
//Console.WriteLine(" Result => " + stValues);
accessToken = stValues.Substring(16);
//Console.WriteLine(" Result => " + accessToken);
accessToken = accessToken.Substring(0,accessToken.Length-2);
// Console.WriteLine(" Result => " + accessToken);
}
}
I am using a c# code to generate access token for my sharepoint site, using client ID and Client Secret.When I am writing the response using HttpWebResponse I am getting 401:Unauthorized.
I have already generated access token using this code and it worked fine. Now I am getting exception in
var response = (HttpWebResponse)myWebRequest.GetResponse();
CommonUtility.stGetAccessTokenUrl = string.Format(CommonUtility.stGetAccessTokenUrl, CommonUtility.tenantID);
myWebRequest = WebRequest.Create(CommonUtility.stGetAccessTokenUrl);
myWebRequest.ContentType = "application/x-www-form-urlencoded";
myWebRequest.Method = "POST";
// Add the below body attributes to the request
/*
* grant_type client_credentials client_credentials
client_id ClientID#TenantID
client_secret ClientSecret
resource resource/SiteDomain#TenantID resourceid/abc.sharepoint.com#tenantID
*/
var postData = "grant_type=client_credentials";
postData += "&client_id=" + CommonUtility.stClientID + "#" + CommonUtility.tenantID;
postData += "&client_secret=" + (CommonUtility.stClientSecret);
postData += "&resource=" + CommonUtility.resourceID + "/" + CommonUtility.stSiteDomain + "#" + CommonUtility.tenantID;
var data = Encoding.ASCII.GetBytes(postData);
using (var stream = myWebRequest.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)myWebRequest.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
string[] stArrResponse = responseString.Split(',');
//get the access token and expiry time ,etc
foreach (var stValues in stArrResponse)
{
if (stValues.StartsWith("\"access_token\":"))
{
//Console.WriteLine(" Result => " + stValues);
accessToken = stValues.Substring(16);
//Console.WriteLine(" Result => " + accessToken);
accessToken = accessToken.Substring(0, accessToken.Length - 2);
// Console.WriteLine(" Result => " + accessToken);
}
}
I have changed client Id and client secret only and it started to give me unauthorized exception. Could anyone help with this?
I would like to try upload a mp3 file to my soundcloud account. I have written this code for this job.
WebClient client = new WebClient();
string postData = "client_id=" + "xxxxx"
+ "&client_secret=" + "xxx"
+ "&grant_type=password&username=" + "xxx" //your username
+ "&password=" + "xxx";//your password :)
string soundCloudTokenRes = "https://api.soundcloud.com/oauth2/token";
string tokenInfo = client.UploadString(soundCloudTokenRes, postData);
tokenInfo = tokenInfo.Remove(0, tokenInfo.IndexOf("token\":\"") + 8);
string token = tokenInfo.Remove(tokenInfo.IndexOf("\""));
System.Net.ServicePointManager.Expect100Continue = false;
var request = WebRequest.Create("https://api.soundcloud.com/tracks") as HttpWebRequest;
request.CookieContainer = new CookieContainer();
//some default headers
request.Accept = "*/*";
request.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.3");
request.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
request.Headers.Add("Accept-Language", "en-US,en;q=0.8,ru;q=0.6");
//file array
var files = new UploadFile[] { new UploadFile(filePath, "#/" + filePath, "application/octet-stream") };
//other form data
var form = new NameValueCollection();
form.Add("track[title]", "biksad");
form.Add("track[sharing]", "public");
form.Add("oauth_token", token);
form.Add("format", "json");
form.Add("Filename", fileName);
form.Add("Upload", "Submit Query");
string lblInfo;
try
{
using (var response = HttpUploadHelper.Upload(request, files, form))
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
lblInfo = reader.ReadToEnd();
}
}
}
catch (Exception ex)
{
lblInfo = ex.ToString();
}
}
When I debug this code part. I get (422) Unprocessable Entity error in catch block. Why I get this error? How can solve this problem?
Check the Soundcloud documentation:
http://developers.soundcloud.com/docs#errors
422 - "The request looks alright, but one or more of the parameters looks a little screwy. It's possible that you sent data in the wrong format (e.g. an array where we expected a string)."
I am trying to connect a twitch TV account to a user profile on my website and I am getting a 403 Forbidden error. I am trying to use the Authorization Code Flow specified here: https://github.com/justintv/Twitch-API/blob/master/authentication.md#auth-code but the 2nd part where I have to Post back to Twitch TV is where I am getting the error. I am doing this with ASP.net MVC3 and C#.
Here is my method to get the code and ask the user to give my application access to twitch TV (This works as expected):
[Authorize]
public ActionResult TwitchTvLogOn(string returnUrl)
{
string redirectUrl = "";
// This is special code used to determine the URL that will be used when working in UGDB since the URL is different in
// development than it is in production.
#if (DEBUG)
redirectUrl = "http://localhost:58386/Account/AuthorizeTwitchTv";
#else
redirectUrl = "http://www.mywebsite.com/Account/AuthorizeTwitchTv";
#endif
var loginUri = "https://api.twitch.tv/kraken/oauth2/authorize?response_type=code&client_id=" +
System.Configuration.ConfigurationManager.AppSettings["TwitchClientId"] +
"&redirect_uri=" + redirectUrl + "&state=" + returnUrl;
return Redirect(loginUri);
}
This is the part that is not working correctly and is giving the 403:
public ActionResult AuthorizeTwitchTv(string code, string state)
{
string currentUrl = Request.Url.AbsoluteUri;
string redirectUrl = "";
#if (DEBUG)
redirectUrl = "http://localhost:58386/Account/AuthorizeTwitchTv";
#else
redirectUrl = "http://www.mywebsite.com/Account/AuthorizeTwitchTv";
#endif
var twitchTvPost = "https://api.twitch.tv/kraken/oauth2/token?client_id=" +
System.Configuration.ConfigurationManager.AppSettings["TwitchClientId"] + "&client_secret=" +
System.Configuration.ConfigurationManager.AppSettings["TwitchAppSecret"] + "&grant_type=authorization_code&redirect_uri=" +
redirectUrl + "&code=" + code;
ASCIIEncoding encoding = new ASCIIEncoding();
string postData = "client_id=" + System.Configuration.ConfigurationManager.AppSettings["TwitchClientId"];
postData += ("&client_secret=" + System.Configuration.ConfigurationManager.AppSettings["TwitchAppSecret"]);
postData += ("&grant_type=authorization_code");
postData += ("&redirect_uri=" + redirectUrl);
postData += ("&code=" + code);
byte[] data = encoding.GetBytes(postData);
// Prepare POST web request...
HttpWebRequest myRequest =
(HttpWebRequest)WebRequest.Create(new Uri("https://api.twitch.tv/kraken/oauth2/token"));
myRequest.Method = "POST";
myRequest.ContentType = "application/x-www-form-urlencoded";
myRequest.ContentLength = data.Length;
Stream newStream = myRequest.GetRequestStream();
// Send the data.
newStream.Write(data, 0, data.Length);
newStream.Close();
// Get response
HttpWebResponse response = (HttpWebResponse)myRequest.GetResponse();
// Get the response stream
StreamReader reader = new StreamReader(response.GetResponseStream());
// Read the whole contents and return as a string
string result = reader.ReadToEnd();
return View();
}
Any help would be greatly appreciated. The overall end goal is to get the "access_token" so I can use it to get the current user's twitch username and be able to grab that user's channels and feeds.
I am not very good with this, but i think the problem is that you are trying to connect to localhost wich is your own computer trough a server port. if this is not the problem and this is what you want. did you think about port forwarding?
I am trying to get user token and build the URL so that user need not login everytime they click the file. below is my code.
My question is do I need to pass whole of the token value shown below or??
The token value I am getting is
symmetric:algorithm:QUVT:keyid:NTZkYTNkNmI=:data:7P9aJHzkfGTOlwtotuWGaMqfU9COECscA9yxMdK64ZLa298A3tsGlHKHDFp0cH+gn/SiMrwKfbWNZybPXaltgo5e4H4Ak8KUiCRKWfS68qhmjfw69qPv9ib96vL3TzNORYFpp/hrwvp8aX4CQIZlBA==
The problem is, once i copy the URL and past it in the browser, it is taking me to the login page. Though I am not getting any errors, it should take users directly to the imageviewer but instead it takes me to login page, if I login it is opening the file correctly.
What am I doing wrong?
string text = "";
string userName = "userName";
string pwd = "*****";
fileNetID = "{5FCE7E04-3D74-4A93-AA53-26C12A2FD4FC}";
Uri uri = null;
string workplaceURL = "http://filenet:9081/WorkPlaceXT";
uri = new Uri(workplaceURL + "/setCredentials?op=getUserToken&userId=" + this.encodeLabel(userName) + "&password=" + this.encodeLabel(pwd) + "&verify=true");
System.Net.WebRequest webRequest = System.Net.WebRequest.Create(uri);
System.Net.WebResponse webResponse = webRequest.GetResponse();
StreamReader streamReader = new StreamReader(webResponse.GetResponseStream());
String token = streamReader.ReadToEnd();
string contentURL = string.Empty;
contentURL = workplaceURL + "/getContent?objectType=document&impersonate=true&objectStoreName=OBJECTSTORE&id=" + HttpUtility.UrlEncode(fileNetID);
contentURL += "&ut=" + HttpUtility.UrlEncode(encodeLabel(token));
return contentURL;
Here is my function, you can see the last couple lines how I unroll the token at the end:
public static string getCEUserToken(string baseURL, string uid, string pwd)
{
string UserToken = "";
System.Net.WebRequest request = System.Net.WebRequest.Create(baseURL + "/setCredentials?op=getUserToken&userId=" + uid + "&password=" + pwd +
"&verify=true");
request.Method = "POST";
System.Net.WebResponse response = request.GetResponse();
Stream stream = response.GetResponseStream();
byte[] token = new byte[response.ContentLength];
stream.Read(token, 0, (int)response.ContentLength);
response.Close();
foreach (byte chr in token)
UserToken += System.Convert.ToChar(chr);
return System.Web.HttpUtility.UrlEncode(UserToken);
}