I'm working with Windows Live SDK from C# trying to invoke directly the rest service for getting my oAuth token, but instead I'm getting an 401 Error. Unauthorized.
I have my application registered as Desktop Application on https://manage.dev.live.com/ and published so I have my own Client ID and Secret Key.
From my desktop application I open an Internet Explorer Window for Live Login and get my Verification Code.
With that code, secret key and clientID I invoke AccessToken.aspx on this way:
try
{
string requestUrl = "https://consent.live.com/AccessToken.aspx";
// Request the access token.
string postData = string.Format("wrap_client_id={0}&wrap_client_secret={1}&wrap_verification_code={2}",
clientId,
secretKey,
verificationCode);
postData = HttpUtility.UrlEncode(postData);
byte[] postDataEncoded = System.Text.Encoding.UTF8.GetBytes(postData);
WebRequest req = HttpWebRequest.Create(requestUrl);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.ContentLength = postDataEncoded.Length;
Stream requestStream = req.GetRequestStream();
requestStream.Write(postDataEncoded, 0, postDataEncoded.Length);
WebResponse res = req.GetResponse();
string responseBody = null;
using (StreamReader sr = new StreamReader(res.GetResponseStream(), Encoding.UTF8))
{
responseBody = sr.ReadToEnd();
}
// Process FORM POST.
NameValueCollection responseCollection = System.Web.HttpUtility.ParseQueryString(responseBody);
return responseCollection["wrap_access_token"];
}
catch (Exception ex)
{
throw ex;
}
What I'm doing wrong?
Thanks in advance for any help provided.
The remote server returned an error: (401) Unauthorized
Related
I want to redirect a system to a centralized authentication server and I need to fill some parameters in headers and redirect to the authentication server completely. Using Web Client or Web Request I must return a value as a response to the requester ( They work as a listener ).
WebClient Send Request Example:
var values = new NameValueCollection();
values["clientId"] = clientId;
values["clientIP"] = currentIP;
byte[] response;
var resultResponse = string.Empty;
using (var client = new WebClient())
{
try {
response = client.UploadValues(url, values);
resultResponse = Encoding.Default.GetString(response);
}
catch (WebException e)
{
string exception = string.Empty;
if (e.Status == WebExceptionStatus.ProtocolError)
{
exception += ((HttpWebResponse)e.Response).StatusCode;
exception += ((HttpWebResponse)e.Response).StatusDescription;
}
}
}
Web Request Example
string method = "post";
WebRequest req = WebRequest.Create(uri);
req.ContentType = contentType;
req.Method = method;
req.Headers.Add("myhead", value);
req.ContentLength = jsonDataBytes.Length;
var stream = req.GetRequestStream();
stream.Write(jsonDataBytes, 0, jsonDataBytes.Length);
stream.Close();
var response = req.GetResponse().GetResponseStream();
StreamReader reader = new StreamReader(response);
var respo = reader.ReadToEnd();
reader.Close();
response.Close();
return respo;
As you see in both methods the requester post the request and is waiting till receiving the response. I can not return to the requester system until I show two view to the user, get the username and passwords and finally process the information. I need to fill headers in a request, post it to the server and also redirect to the central authentication server. I searched a lot and found that it is impossible to post and redirect at a same time. Can you suggest any other methods to me?
I can get the access key just fine, but I'm getting a (400) Bad Request error when attempting to get the token with the following code. I have tried everything. I know the credentials are correct because they work with the Google API Client. That being said, I can't use that because I need this to run in the 3.5 framework. Is there anything glaringly wrong here?
private const string clientId = "1003120056405-ofafvc699hjujp0a9952g8vjaludk90j.apps.googleusercontent.com";
private const string clientSecret = "******************";
private string redirectURI = "urn:ietf:wg:oauth:2.0:oob:auto";
public static AuthResponse Exchange(string authCode, string clientid, string secret, string redirectURI){
try
{
var request = (HttpWebRequest)WebRequest.Create("https://accounts.google.com/o/oauth2/token");
string postData = string.Format("code={0}&client_id={1}&client_secret={2}&redirect_uri={3}&grant_type=authorization_code&scope={4}", HttpUtility.UrlEncode(authCode), clientid, secret, redirectURI, "");
var data = Encoding.ASCII.GetBytes(postData);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded; charset=utf-8";
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
MessageBox.Show(responseString);
return null;
}
catch (WebException ex)
{
MessageBox.Show(ex.Message);
return null;
}
}
I got this working. The code above was fine, but my accessKey was being converted to lower case by mistake. The key is case sensitive to check out the token.
i used following code to get the access token from code as below
String code = HttpContext.Current.Request["code"];
string redirecturl = HttpContext.Current.Request["url"];
string Url = "https://accounts.google.com/o/oauth2/token";
string grant_type = "authorization_code";
string redirect_uri_encode = UrlEncodeForGoogle(url);
string data = "code={0}&client_id={1}&client_secret={2}&redirect_uri={3}&grant_type={4}&access_type={5}";
HttpWebRequest request = HttpWebRequest.Create(Url) as HttpWebRequest;
string result = null;
request.Method = "POST";
request.KeepAlive = true;
request.ContentType = "application/x-www-form-urlencoded";
string param = string.Format(data, code,configurationInfo.oauthclientid , configurationInfo.oauthclientsecretid, redirect_uri_encode, grant_type, "offline");
var bs = Encoding.UTF8.GetBytes(param);
using (Stream reqStream = request.GetRequestStream())
{
reqStream.Write(bs, 0, bs.Length);
}
using (WebResponse response = request.GetResponse())
{
var sr = new StreamReader(response.GetResponseStream());
result = sr.ReadToEnd();
sr.Close();
}
i am getting response as
The remote server returned an error: (400) Bad Request.
i do not know where i went wrong
waiting for your valuable comments
Google also provides a higher level library for accessing its services. I find it makes it much easier to work with its APIs.
http://code.google.com/p/google-api-dotnet-client/
may i know is there any foursquare sdk for .NET C#.
I am doing based on the developer reference but i failed to do it during request for token, i keep on getting the error.
I am using VS 2008 and under development server. I search before this error because of url rewriting, but i'm not hosted in IIS and i also have check the web.config, no luck also. Please help, thanks.
This is my error:
The HTTP verb POST used to access path '/login' is not allowed.
This is my implementation:
HttpWebRequest request = null;
HttpWebResponse response = null;
StreamReader responseStream = null;
ASCIIEncoding ascii = null;
string key = ConfigurationManager.AppSettings["key"];
string secret = ConfigurationManager.AppSettings["secret"];
string callback = ConfigurationManager.AppSettings["callback"];
string obtainTokenUrl = ConfigurationManager.AppSettings["obtainTokenUrl"];
try
{
string postData = "client_id=" + key + "&response_type=code&redirect_uri=" + callback;
ascii = new ASCIIEncoding();
byte[] postBytes = ascii.GetBytes(postData);
try
{
request = WebRequest.Create(obtainTokenUrl) as HttpWebRequest;
}
catch (UriFormatException)
{
request = null;
}
if (request == null)
{
throw new ApplicationException("Invalid URL: " + obtainTokenUrl);
}
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postBytes.Length;
//add post data to request
Stream postStream = request.GetRequestStream();
postStream.Write(postBytes, 0, postBytes.Length);
postStream.Close();
response = (HttpWebResponse)request.GetResponse();
Encoding encode = Encoding.GetEncoding("utf-8");
responseStream = new StreamReader(response.GetResponseStream(), encode);
Response.Write(responseStream.ReadToEnd());
Well, this may be a roundabout sort of answer. But maybe you could check out the open source 4square app for windows phone 7:
http://4square.codeplex.com/
Since you can look at the source code, you can see how they are interfacing with the 4sq API :-)
SharpSquare - FourSquare SDK for .NET http://www.igloolab.com/sharpsquare/
I'm trying to get the access token from the windows live connect api by using this code
string requestUrl = "https://consent.live.com/AccessToken.aspx";
// Request the access token.
string postData = string.Format("{0}?wrap_client_id={1}&wrap_client_secret={2}&wrap_callback={3}&wrap_verification_code={4}&idtype={5}",
requestUrl,
"000000004C039809",
"l4VJekL1vFL1iFVmcP5qLkWv9ukY4mdl",
"http://ewshops.com",
"dac5d71d-d640-30d1-ebed-3576b132b3ec",
"cid");
byte[] postDataEncoded = System.Text.Encoding.UTF8.GetBytes(postData);
WebRequest req = HttpWebRequest.Create(requestUrl);
req.Method = "POST";
// req.
req.ContentType = "application/x-www-form-urlencoded";
req.ContentLength = postDataEncoded.Length;
Stream requestStream = req.GetRequestStream();
requestStream.Write(postDataEncoded, 0, postDataEncoded.Length);
WebResponse res = req.GetResponse();
string responseBody = null;
using (StreamReader sr = new StreamReader(res.GetResponseStream(), Encoding.UTF8))
{
responseBody = sr.ReadToEnd();
}
// Process FORM POST.
NameValueCollection responseCollection = System.Web.HttpUtility.ParseQueryString(responseBody);
return responseCollection["wrap_access_token"];
but I've recieved the following error
The remote server returned an error: (401) Unauthorized.
Show us the response body, it usually contains more information. You should also urlencode http://ewshops.com before adding it to the uri.
I had the same problem and fixed it as follows. Remove the requestUrl ("https://consent.live.com/AccessToken.aspx") and the subsequent "?" from your postData. The POST data should be in x-www-form-urlencoded format and that does not include the request URL. Also HttpUtility.UrlEncode() all the parameters.