This is less a question than an answer. I figured I would want to share this with you, since I was a bit confused finding so litte about the ebay OAuth 2.0 in combination with a C# web application.
I tried starting to use the RESTsharp library, but got stuck at the point, where the body content was created. RESTsharp prefers XML or JSON, ebay want's a string with params.
So to give you all a little help if you run into the same issue, I decided to post my solution (not using RESTsharp).
public class HomeController : Controller {
string clientId = "YOUR_CLIENT_ID";
string clientSecret = "YOUR_CLIENT_SECRET";
string ruName = "YOUR_RU_NAME";
// Redirect the request to get a request token
public ActionResult Index() {
var authorizationUrl =
"https://signin.sandbox.ebay.de/authorize?" +
"client_id=" + clientId + "&" +
"redirect_uri=" + ruName + "&" +
"response_type=code";
Response.Redirect(authorizationUrl);
return View();
}
// I used Test as a method to test the result in the controller, use your apropriate method here
public ActionResult Test(string code)
{
ViewBag.Code = code;
// Base 64 encode client Id and client secret
var clientString = clientId + ":" + clientSecret;
byte[] clientEncode = Encoding.UTF8.GetBytes(clientString);
var credentials = "Basic " + System.Convert.ToBase64String(clientEncode);
HttpWebRequest request = WebRequest.Create("https://api.sandbox.ebay.com/identity/v1/oauth2/token")
as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.Headers.Add(HttpRequestHeader.Authorization, credentials);
var codeEncoded = HttpUtility.UrlEncode(code);
var body = "grant_type=authorization_code&code=" + codeEncoded + "&redirect_uri=" + ruName;
// Encode the parameters as form data
byte[] formData = UTF8Encoding.UTF8.GetBytes(body);
request.ContentLength = formData.Length;
// Send the request
using (Stream post = request.GetRequestStream())
{
post.Write(formData, 0, formData.Length);
}
// Pick up the response
string result = null;
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
StreamReader reader = new StreamReader(response.GetResponseStream());
result = reader.ReadToEnd();
}
ViewBag.Response = result;
return View();
}
If you output ViewBag.Response you will see the authorization code. Have fun.
How is your redirect url looking in sandbox? Seems like the url should be https. In this stage in dev environment and don't have server with https. How did you deal with that?
Ta
Related
So I am trying to fetch my classes from my google classroom into my application:
Here is my google url:
var Googleurl = "https://accounts.google.com/o/oauth2/v2/auth?redirect_uri=" + googleplus_redirect_url + "&prompt=consent&response_type=code&client_id=" + googleplus_client_id + "&scope=https://www.googleapis.com/auth/userinfo.profile+https://www.google.com/m8/feeds/+https://www.googleapis.com/auth/drive+https://www.googleapis.com/auth/drive.appdata+https://www.googleapis.com/auth/drive.file+https://www.googleapis.com/auth/drive.metadata+https://www.googleapis.com/auth/classroom.courses+https://www.googleapis.com/auth/classroom.profile.emails+https://www.googleapis.com/auth/classroom.profile.photos+https://www.googleapis.com/auth/classroom.rosters+https://www.googleapis.com/auth/classroom.rosters.readonly&access_type=offline";
After this I request for the access codes through:
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("https://accounts.google.com/o/oauth2/token");
webRequest.Method = "POST";
Parameters = "code=" + code + "&client_id=" + googleplus_client_id + "&client_secret=" + googleplus_client_sceret + "&redirect_uri=" + googleplus_redirect_url + "&grant_type=authorization_code";
byte[] byteArray = Encoding.UTF8.GetBytes(Parameters);
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.ContentLength = byteArray.Length;
Stream postStream = webRequest.GetRequestStream();
// Add the post data to the web request
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
WebResponse response = webRequest.GetResponse();
postStream = response.GetResponseStream();
StreamReader reader = new StreamReader(postStream);
string responseFromServer = reader.ReadToEnd();
GooglePlusAccessToken serStatus = JsonConvert.DeserializeObject<GooglePlusAccessToken>(responseFromServer);
I am able to get the access code as well as the refresh token all fine.
Now when I wish to fetch my classroom by:
string p="https://classroom.googleapis.com/v1/courses";
string auth = "Bearer "+access_token;
private bool GetClasses(string p,string auth)
{
using (var client = new WebClient())
{
var uri = new Uri(p);
//client.DefaultRequestHeaders.Authorization=new AuthenticationHeaderValue("Bearer", auth);
string req="Authorization: "+ auth;
client.Headers.Add(req);
var response = client.DownloadString(uri);
}
return true;
}
This code return an error of type:System.Net.WebException: {"The remote server returned an error: (403) Forbidden."}
I have used the same access_token to get all other scopes as shown in the scopes parameter in mu Googleurl. However I am unable to access my classes even though I've added the respective scopes for it.
Apparently to use google classroom related functionalities we need to enable the google classroom Api. As silly as it may sound I was ignorant about it(As I had already enabled the google Api service). Just had to activate the classroom api and the code worked like a charm.
Just started at a new company and we all use Jira, the customers are determined to not use it as they don't like it so I have decided to build a simple Windows Form when they can both Log tickets and get Updates and Comments in a nice simple UI.
Now I have never done any coding before 2 weeks ago so it has been a struggle to get my head around both C# and Rest (Have made scripts for basic IT fixes but never anything as complex as this!)
Back onto point, Set up and got a Rest API set up with a Rest Client but everytime I try pull data from a ticket on Jira I get the error:
{"errorMessages":["You do not have the permission to see the specified issue.","Login Required"],"errors":{}}
Here is the code from the Form:
private void button3_Click_1(object sender, EventArgs e)
{
var client = new RestClient("https://jira.eandl.co.uk/rest/api/2/issue/ITREQ-" + textBox1.Text
);
client.Authenticator = new SimpleAuthenticator("username", "abc", "password", "123");
var request = new RestRequest(Method.GET);
request.AddParameter("token", "saga001", ParameterType.UrlSegment);
// request.AddUrlSegment("token", "saga001");
request.OnBeforeDeserialization = resp => { resp.ContentType = "application/json"; };
var queryResult = client.Execute(request);
Console.WriteLine(queryResult.Content);
}
And here is the code from the Rest Client itself:
public Restclient()
{
endPoint = string.Empty;
httpMethod = httpVerb.GET;
}
private string logonAttempt;
public string makeRequest()
{
string strResponseValue = string.Empty;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(endPoint);
request.Method = httpMethod.ToString();
String authHeader = System.Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(userName + ":" + userPassword));
request.Headers.Add("Authorization", authType.ToString() + " " + authHeader);
HttpWebResponse response = null;
try
{
response = (HttpWebResponse)request.GetResponse();
//Process the Response Stream... (Could be JSON, XML ot HTML etc...)
using (Stream responseStream = response.GetResponseStream())
{
if (responseStream != null)
{
using (StreamReader reader = new StreamReader(responseStream))
{
strResponseValue = reader.ReadToEnd();
}//End of Stream Reader
}
}//end of Response Stream
}
catch (Exception ex)
{
strResponseValue = "(\"errorMessages\":[\"" + ex.Message.ToString() + "\"],\"errors\":{}}";
}
finally
{
if(response != null)
{
((IDisposable)response).Dispose();
}
}
return strResponseValue;
}
}
}
Now obviously I am expecting that I have missed something absolutely bigginer as like I said, I've never taken on a project like this before and had 0 experience.
Just looking for someone to bluntly tell me what I'm doing wrong
Changed to this as per answer:
private void button3_Click_1(object sender, EventArgs e)
{
var client = new
RestClient("https://jira.eandl.co.uk/rest/api/2/issue/ITREQ-" + textBox1.Text
);
client.Authenticator = new HttpBasicAuthenticator("username", "password");
var request = new RestRequest(Method.GET);
string authHeader = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes("cdale!" + ":" + "Chantelle95!"));
request.AddHeader("Authorization", "Basic " + authHeader);
request.OnBeforeDeserialization = resp => { resp.ContentType = "application/json"; };
var queryResult = client.Execute(request);
Console.WriteLine(queryResult.Content);
}
By default with the Jira REST API, you can use Basic Authentication or OAuth2. I think that more easy way for you will be to use the Basic one.
I'm not sure why you have a class where you define your custom RestClient since the first block of code uses the RestSharp one from http://restsharp.org.
In this case, you will need to modify your authenticator:
client.Authenticator = new HttpBasicAuthenticator(userName, password);
And I think that you should remove the line where you specify a token. I don't think that it's required.
Finally, the class Restclient doesn't seem to be used, then remove it.
You could also uses what you have created in your custom RestClient and manually specify a Basic header:
string authHeader = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(userName + ":" + userPassword));
request.AddHeader("Authorization", "Basic " + authHeader);
However, it's essentially the behavior of the HttpBasicAuthenticator class.
If you don't want to encode your credentials in every request here is how to do it using cookies.
When requesting the cookie you don't need to add any authorization on the headers. This method will accept a JSON string with the user name and password and the URL. It will return the cookie values.
public async Task<JiraCookie> GetCookieAsync(string myJsonUserNamePassword, string JiraCookieEndpointUrl)
{
using (var client = new HttpClient())
{
var response = await client.PostAsync(
JiraCookieEndpointUrl,
new StringContent(myJsonUserNamePassword, Encoding.UTF8, "application/json"));
var json = response.Content.ReadAsStringAsync().Result;
var jiraCookie= JsonConvert.DeserializeObject<JiraCookie>(json);
return jArr;
}
}
public class JiraCookie
{
public Session session { get; set; }
}
public class Session
{
public string name { get; set; }
public string value { get; set; }
}
When I call it using url: http://[baseJiraUrl]/rest/auth/1/session it returns the following JSON response:
{
"session" : -{
"name" : JSESSIONID,
"value" : cookieValue
}
Keep in mind the URL above is valid in the version of JIRA I'm using and may vary depending on which version you're using. Read the JIRA API documentation for the correct URL for the version you are using. I'm using the following:
https://docs.atlassian.com/software/jira/docs/api/REST/7.6.1/#auth/1/session
Remember you'll have to store your cookie and use it on every subsequent request.
Check out this answer on how add cookies to your HttpClient request: How do I set a cookie on HttpClient's HttpRequestMessage.
Once you're done with the cookie (logging out) simply send a delete http request with the same URL as the post.
Reference: https://stackoverflow.com/a/49109192/7763903
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 using the following code on Page_Load of facebook_login page in asp.net web application. After redirecting this url I have got the accesstoken in url but when I try to access this current url via HttpContext.Current.Request.Url.AbsoluteUri it gave the url of app where it is published not the url which is currently in window.
How can I access this access token or userdetails?
var uriParams = new Dictionary<string, string>() {
{"client_id", facebookAppId},
{"response_type", "token"},
{"scope", "user_about_me, read_stream, email"},
{"redirect_uri", "http://apps.facebook.com/appNameHere/"}
};
StringBuilder urlBuilder = new StringBuilder();
foreach (var current in uriParams)
{
if (urlBuilder.Length > 0)
{
urlBuilder.Append("&");
}
var encoded = HttpUtility.UrlEncode(current.Value);
urlBuilder.AppendFormat("{0}={1}", current.Key, encoded);
}
var loginUrl = "http://www.facebook.com/dialog/oauth?" + urlBuilder.ToString();
Response.Redirect(loginUrl);
In Facebook you can set call back url value which should point to your web application. So once you make request to http://www.facebook.com/dialog/oauth and after successfully login Facebook redirect to Callback Url (which is your web application).
Then you have to make call to url : https://graph.facebook.com/oauth/access_token something like this:
StringBuilder uri = new StringBuilder();
uri.Append("https://graph.facebook.com/oauth/access_token?");
uri.Append("client_id=" + ClientKey + "&");
uri.Append("redirect_uri=" + Curl + "&");
uri.Append("scope=offline_access&");
uri.Append("client_secret=" + ClientSecret + "&");
uri.Append("code=" + OAuthCode);
HttpWebRequest req = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(uri);
req.Headers.Add("Authorization", String.Empty);
req.Method = "POST";
req.ServicePoint.Expect100Continue = false;
req.ContentLength = 0;
req.ContentType = "application/x-www-form-urlencoded";
HttpWebResponse resp;
try
{
resp = (HttpWebResponse)req.GetResponse();
System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());
string result = sr.ReadToEnd().Trim();
string[] resultCollection = Regex.Split(result, "&");
string access_token = Regex.Split(resultCollection[0], "=")[1];//This is the access token
//which you want and you can save it to database or some where for further use.
}
catch (WebException ex)
{
resp = (HttpWebResponse)ex.Response;
//pass on the exception
throw ex;
}
UPDATE :
OAuthCode you can get like this, it is available when after successfully login FB redirect to your web app page
OAuthCode = Request.Params["code"];
Header you can pass empty like String.Empty
I'm coding a C#.Net WPF 4.0 application that connects to Facebook and Twitter via oauth. With Facebook Graph API, I'm able to authorize, sign-in with oauth, exchange a temporary access_token to a almost persistent access token, and then, fetch any data only by adding the access_token next to my query, or posting on the wall, like this: [http://Url/query/access_token], and all of this without any SDK or any other library.
I tried to do the same with Twitter but I'm all mixed-up. I've been searching for examples on how to fetch some Json data the same way I do in Facebook, but I found nothing, probably because I don't know what to search. What is the flow that I need to follow to be able to make queries with only a direct url and a token?
you should do the following:
Get access token for the user: https://dev.twitter.com/docs/auth/obtaining-access-tokens
Use one of the REST APIs: https://dev.twitter.com/docs/api
Generate OAuth header and insert it into your request. Below is code from my app which uploads tweet and images into twitter - but GET requests will be similar. NOTE: I'm using 3rd-party OAuth class from https://cropperplugins.svn.codeplex.com/svn/Cropper.Plugins/TwitPic/OAuth.cs
var oauth = new OAuth.Manager();
oauth["consumer_key"] = Settings.TWITTER_CONSUMER_KEY;
oauth["consumer_secret"] = Settings.TWITTER_CONSUMER_SECRET;
oauth["token"] = item.AccessToken;
oauth["token_secret"] = item.AccessSecret;
var url = "https://upload.twitter.com/1/statuses/update_with_media.xml";
var authzHeader = oauth.GenerateAuthzHeader(url, "POST");
foreach (var imageName in item.Images.Split('|'))
{
var fileData = PhotoThubmnailBO.GetThumbnailForImage(imageName, ThumbnailType.FullSize).Photo;
// this code comes from http://cheesoexamples.codeplex.com/wikipage?title=TweetIt&referringTitle=Home
// also see http://stackoverflow.com/questions/7442743/how-does-one-upload-a-photo-to-twitter-with-the-api-function-post-statuses-updat
var request = (HttpWebRequest) WebRequest.Create(url);
request.Method = "POST";
request.PreAuthenticate = true;
request.AllowWriteStreamBuffering = true;
request.Headers.Add("Authorization", authzHeader);
string boundary = "~~~~~~" +
Guid.NewGuid().ToString().Substring(18).Replace("-", "") +
"~~~~~~";
var separator = "--" + boundary;
var footer = "\r\n" + separator + "--\r\n";
string shortFileName = imageName;
string fileContentType = GetMimeType(shortFileName);
string fileHeader = string.Format("Content-Disposition: file; " +
"name=\"media\"; filename=\"{0}\"",
shortFileName);
var encoding = Encoding.GetEncoding("iso-8859-1");
var contents = new StringBuilder();
contents.AppendLine(separator);
contents.AppendLine("Content-Disposition: form-data; name=\"status\"");
contents.AppendLine();
contents.AppendLine(item.UserMessage);
contents.AppendLine(separator);
contents.AppendLine(fileHeader);
contents.AppendLine(string.Format("Content-Type: {0}", fileContentType));
contents.AppendLine();
// actually send the request
request.ServicePoint.Expect100Continue = false;
request.ContentType = "multipart/form-data; boundary=" + boundary;
using (var s = request.GetRequestStream())
{
byte[] bytes = encoding.GetBytes(contents.ToString());
s.Write(bytes, 0, bytes.Length);
bytes = fileData;
s.Write(bytes, 0, bytes.Length);
bytes = encoding.GetBytes(footer);
s.Write(bytes, 0, bytes.Length);
}
using (var response = (HttpWebResponse) request.GetResponse())
{
if (response.StatusCode != HttpStatusCode.OK)
{
throw new Exception(response.StatusDescription);
}
}
}