We have a website. We usually use Microsoft forefront for asking the user for its username and password to log in. Recently, we have a requirement to allow users to use Office365 to log in to our website. So we have to integrate Office365 into our website to allows a user to login into our website using Office365. So I am trying to use Microsoft.Graph. I have registered my app as web and got the client ID and well as a secret key. I am using this information to make a call to Microsoft Graph.
I have tried to call API as shown below. My first request(request1) is successful by second request (request2) throws an error saying its a bad request
"The remote server returned an error: (400) Bad Request." System.Net.WebException**
var request1 = (HttpWebRequest)WebRequest.Create("https://login.microsoftonline.com/{tenant}/adminconsent?client_id=myclientidvalue&state=12345&redirect_uri=http://localhost:36541/");
var response1 = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response1.GetResponseStream()).ReadToEnd();
var request2 = (HttpWebRequest)WebRequest.Create("https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token");
var postData = "client_id=myclientid";
postData += "&scope=http://localhost:36541/.default";
postData += "&client_secret=mysecretkey";
postData += "&grant_type=client_credentials";
var data = Encoding.ASCII.GetBytes(postData);
request2.Method = "POST";
request2.ContentType = "application/x-www-form-urlencoded";
request2.ContentLength = data.Length;
request1.Host = "login.microsoftonline.com";
using (var stream = request2.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response2 = (HttpWebResponse)request2.GetResponse();
var responseString1 = new StreamReader(response2.GetResponseStream()).ReadToEnd();
Related
I am developing C# WinForms application to trade on Stex.com.
They upgraded their api to api3.
It uses google authentication app to login.
That's why there's no way to get access token without man's behavior.
Finally, I determined to use postman to get access token and I want to refresh token when the token is expired.
I think it the best way.
So I got the access token and refresh token via postman.
https://help.stex.com/en/articles/2740368-how-to-connect-to-the-stex-api-v3-using-postman .
now it's the turn to refresh my token.
so this is what I wrote.
string refresh_token = "def50200b03974080...";
string client_id = "502";
string client_secret = "SeTs50aFxV1RoMFBW1b4RVNQhh2wEdICaYQrpE3s";
string AccessToken = "eyJ0eXAiOiJKV1QiLCJhbGciO...";
string url = #"https://api3.stex.com/oauth/token";
var request = HttpWebRequest.Create(url);
request.Method = "POST";
request.Headers.Add("Authorization", "Bearer " + AccessToken);
request.ContentType = "application/x-www-form-urlencoded";
NameValueCollection outgoingQueryString = HttpUtility.ParseQueryString(String.Empty);
outgoingQueryString.Add("grant_type", "refresh_token");
outgoingQueryString.Add("refresh_token", refresh_token);
outgoingQueryString.Add("client_id", client_id);
outgoingQueryString.Add("client_secret", client_secret);
outgoingQueryString.Add("scope", "trade profile reports");
outgoingQueryString.Add("redirect_uri", #"https://www.getpostman.com/oauth2/callback");
byte[] postBytes = new ASCIIEncoding().GetBytes(outgoingQueryString.ToString());
Stream postStream = request.GetRequestStream();
postStream.Write(postBytes, 0, postBytes.Length);
postStream.Flush();
postStream.Close();
using (WebResponse response = request.GetResponse())
{
using (StreamReader streamReader = new StreamReader(response.GetResponseStream()))
{
dynamic jsonResponseText = streamReader.ReadToEnd();
}
}
It shows 401(Unauthorized) error.
And when I remove ContentType, it shows 400(Bad Request) error.
If anyone did this, please help me.
guys!
Finally, I found the issue.
The issue was due to my ignorance.
Calm down and have a relax when you get issue.
:)
I created 2 api3 clients and so client_secret was different.
Thank you.
I am trying to run following code it works fine when runs on localhost IIS but returns error when hosted on my web server IIS
Error : -- The remote server returned an error: (401) Unauthorized. at System.Net.HttpWebRequest.GetResponse() at _Default.btnsubmit_Click(Object sender, EventArgs e) in e:\WebSite1\Default.aspx.cs:
try
{
var webAddr = "http://serviceserver/someService";
var httpWebRequest = (HttpWebRequest)WebRequest.Create(webAddr);
httpWebRequest.ContentType = "text/xml";
httpWebRequest.ContentLength = 0;
httpWebRequest.Method = "GET";
httpWebRequest.Credentials = new NetworkCredential("user", "password");
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new treamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
Label1.Text = result;
}
}
catch (Exception ex)
{
Response.Write(ex.Message);
Response.Write(ex.StackTrace);
Response.Write(ex.InnerException);
}
Update
The above service URL is WCF service and it is secured via transport credentials in windows
I am trying to hit this URL via my web application and passing my credentials as Network Credentials.
When I run this web application on my local machine it runs fine and returns the required data.
But when I host this application I got above stated error. Am I doing something wrong.
You need to look on your server for a username, pass, and if it is basic or digest. I set my command up like this:
HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(uri);
var cache = new CredentialCache();
cache.Add(new Uri(uri), "Digest", new NetworkCredential("administrator", "admin"));
httpRequest.Credentials = cache;
httpRequest.PreAuthenticate = true;
using (HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse())
{
//DO CODE
}
Before implementing an httpRequest in code, you should check it in a browser first. Enter your link in a browser and see if it brings up what you want.
I need to hit a service to obtain the app ticket to authenticate against another service. The solution is hosted on a endpoint.
I tried using the POSTMAN app in google chrome and it succeeds and returns me the AppID. When I submit the (POST)request in POSTMAN app, it prompts for a certificate. When I select the correct certificate the call succeeds.
I need to implement the same in C# (in a web application)
I tried using the RestSharp.RestClient library and am constantly getting the following error:
"Client certificate not found in site certificates".
Attaching the code for reference.
var client = new RestSharp.RestClient("MyUrl");
var request = new RestSharp.RestRequest("pksecure/oauth20_clientcredentials.srf", RestSharp.Method.POST);
request.AddParameter("grant_type", "client_credentials");
request.AddParameter("param2", "value2");
request.AddParameter("scope", "machinename");
client.ClientCertificates = new System.Security.Cryptography.X509Certificates.X509CertificateCollection();
client.ClientCertificates.Add(new System.Security.Cryptography.X509Certificates.X509Certificate(
#"E:\MyCertificate.pfx"
, "MyPassword"
));
System.Net.ServicePointManager.ServerCertificateValidationCallback +=
delegate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate cert, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslError)
{
bool validationResult = true;
return validationResult;
};
var response = client.Execute(request);
var content = response.Content; // raw content as string
Pls. help to make this call using the mutual TLS.
TIA,
Sam.
I am not sure why I was not able to get it done using RestSharp.
But I could get it working by using HttpWebRequest Instead.
Also, earlier I was using the Certficate.Pfx file which caused the error. Using the Certificate.Cer file solved the issue.
Posting the code for reference:
var request = (HttpWebRequest)WebRequest.Create("MyURL/oauth20_clientcredentials.srf");
var postData = "grant_type=client_credentials";
postData += "¶m2=value2";
postData += "&scope=" + HttpUtility.UrlEncode("machinename");
var data = Encoding.ASCII.GetBytes(postData);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
request.ClientCertificates.Add(new System.Security.Cryptography.X509Certificates.X509Certificate(#"E:\MyCertificate.cer"));
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
return appToken;
Thanks,
Sam Jayander Thiagarajan.
I am implementing Yahoo OAuth 2.0 given in the guide -https://developer.yahoo.com/oauth2/guide/
I am successful in getting the Access Code given in step 4 but in step 5 which says 'Exchange refresh token for new access token' my code is failing with error - 'The remote server returned an error: (401) Unauthorized.'
My application is placed in http://www.example.com/TutorialCode/YahooOAuth2.0/yahoooauth2.aspx and it gets the Access Token.
Now i am requesting the new access token from the refresh token in another page - http://www.example.com/TutorialCode/YahooOAuth2.0/newaccesstoken.aspx
that is the refresh token i copy and paste from previous page to this page and click button to get new access token but it is failing. My code is -
HTML
<asp:TextBox placeholder="Refresh Token" ID="refreshTokenTextBox" runat="server"></asp:TextBox>
<asp:Button ID="newAccessTokenButton" runat="server" Text="Get New Access Token" OnClick="newAccessTokenButton_Click" />
<div id="newDataDiv" runat="server"></div>
C#
protected void newAccessTokenButton_Click(object sender, EventArgs e)
{
string consumerKey = "xxxx";
string consumerSecret = "myconsumerkey";
string returnUrl = "http://www.example.com/TutorialCode/YahooOAuth2.0/newaccesstoken.aspx";
//string encodedReturnUrl = System.Web.HttpUtility.UrlEncode(returnUrl);
/*Exchange authorization code for Access Token by sending Post Request*/
Uri address = new Uri("https://api.login.yahoo.com/oauth2/get_token");
// Create the web request
HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
// Set type to POST
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
byte[] headerByte = System.Text.Encoding.UTF8.GetBytes(consumerKey + ":" + consumerSecret);
string headerString = System.Convert.ToBase64String(headerByte);
request.Headers["Authorization"] = "Basic " + headerString;
// Create the data we want to send
StringBuilder data = new StringBuilder();
data.Append("client_id=" + consumerKey);
data.Append("&client_secret=" + consumerSecret);
data.Append("&redirect_uri=" + returnUrl);
data.Append("&refresh_token =" + refreshTokenTextBox.Text.Trim());
data.Append("&grant_type=refresh_token");
// Create a byte array of the data we want to send
byte[] byteData = UTF8Encoding.UTF8.GetBytes(data.ToString());
// Set the content length in the request headers
request.ContentLength = byteData.Length;
// Write data
using (Stream postStream = request.GetRequestStream())
{
postStream.Write(byteData, 0, byteData.Length);
}
// Get response
string responseFromServer = "";
try
{
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
// Get the response stream
StreamReader reader = new StreamReader(response.GetResponseStream());
responseFromServer = reader.ReadToEnd();
//ShowNewReceivedData(responseFromServer);
newDataDiv.InnerHtml = responseFromServer;
}
}
catch (Exception ex)
{
Response.Write(ex.Message+"<br/>"+ex.ToString());
}
}
Can somebody help me in getting the root cause of the problem?
Thanks
You need to URL encode the parameter values in the request. They may contain characters like & or = that would break the form encoding.
Other than that you may want to swap the legacy POST approach for a more recent, easier approach, as described in the answer in HTTP request with post
You can check your parameters with a curl command:
curl -u "${consumerKey}:${consumerSecret}" -d "grant_type=refresh_token&redirect_uri=${returnUrl}&refresh_token=${refreshToken}" https://api.login.yahoo.com/oauth2/get_token
I have an application hosted on one server that's not a part of my SharePoint farm. I need it to to post a new list item to a SharePoint List. The Default SharePoint Zone (where it will be posted to) is configured to use Claims Authentication, Integrated Windows Authentication.
The identity that the application is running under has full administrative access over the list that I'm trying to post to. Every time I post I get a "403 forbidden" error. If I remove the endPointRequest.credentials line I get a 401 error.
var data = "{'__metadata':{'type':'SP.Data.SpecialListItem'}, 'Special':'" + txtSpecial + "'}";
HttpWebRequest endpointRequest = (HttpWebRequest)HttpWebRequest.Create("http://portal/_api/web/List/GetByTitle('Special')");
endpointRequest.Credentials = CredentialCache.DefaultNetworkCredentials;
endpointRequest.Method = "POST";
endpointRequest.Accept = "application/json;odata=verbose";
endpointRequest.ContentType = "application/json;odata=verbose";
endpointRequest.ContentLength = data.Length;
StreamWriter writer = new StreamWriter(endpointRequest.GetRequestStream());
writer.Write(data);
writer.Flush();
using (HttpWebResponse endpointResponse = (HttpWebResponse)endpointRequest.GetResponse())
{
using (StreamReader reader = new StreamReader(endpointResponse.GetResponseStream()))
{
string result = reader.ReadToEnd();
}
}