Twitter Authentication Error - c#

I'm trying to get an authorization token for the Twitter REST api but it seems I'm doing something wrong. Is there something wrong with my code?
//Authorization
var customerKey = "xxxxxxxxxx";
var customerSecret = "xxxxxxxxxxxxxxxxxxx";
var b64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format("{0}:{1}", WebUtility.UrlEncode(customerKey), WebUtility.UrlEncode(customerSecret))));
var req = new HttpRequestMessage(HttpMethod.Post, "https://api.twitter.com/oauth2/token");
req.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", b64);
req.Content = new FormUrlEncodedContent(new Dictionary<string, string>() {
{ "grant_type", "client_credentials" }
});
var token = "";
using (var res = await http.SendAsync(req))
{
if (res.IsSuccessStatusCode)
token = Regex.Match(await res.Content.ReadAsStringAsync(), "\"access_token\":\"([^\"]+)").Groups[1].Value;
}
http.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer ", token);
In response I'm getting this message:
{"errors":[{"code":99,"message":"Unable to verify your credentials","label":"authenticity_token_error"}]}

Related

Graphclient ArgumentException: Only HTTP/1.0 and HTTP/1.1 version requests are currently supported. Parameter name: value

Using GraphClient from Microsoft.SDK.Graph I can see the queries are going out in fiddler,
none of them use HTTP/2.0 but I get this error:
ArgumentException: Only HTTP/1.0 and HTTP/1.1 version requests are currently supported. Parameter name: value
private async Task<UserAccount> FetchAzurePropsFromGraph()
{
var scopes = new[] { "User.Read" };
var clientId = EWSMailboxSyncProvider.CLIENT_ID;
var tenantId = ServicesConfiguration.GetStoredTenantID();
System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
var transport = new Azure.Core.Pipeline.HttpClientTransport(client);
var options = new TokenCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
Transport = transport
};
var userNamePasswordCredential = new UsernamePasswordCredential(
_o365UserName, _o365Password, tenantId, clientId, options);
var graphClient = new Microsoft.Graph.GraphServiceClient(userNamePasswordCredential, scopes);
var user = await graphClient.Users[_emailAddress].Request().GetAsync();
var result = new UserAccount();
if (user != null)
{
result.DisplayName = user.DisplayName;
result.City = user.City;
result.Company = user.CompanyName;
result.DisabledAccount = !(user.AccountEnabled ?? true);
result.DistinguishedName = user.OnPremisesDistinguishedName;
result.DomainName = user.OnPremisesDomainName;
result.EmailAddresses.Add(user.Mail);
foreach (var mail in user.OtherMails)
{
result.EmailAddresses.Add(mail);
}
}
return result;
}
I'm the same issue with you, and i solved it by create custom request to Microsoft server
public static string GetAzureAccessToken(){
var client = new RestClient("https://login.microsoftonline.com:443/your_tenantid/oauth2/v2.0/token");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("grant_type", "password");
request.AddParameter("username", "your_email");
request.AddParameter("password", "password");
request.AddParameter("scope", "https://graph.microsoft.com/.default");
request.AddParameter("tenant", "your_tenantid");
request.AddParameter("client_id", "your_client_id");
IRestResponse response = client.Execute(request);
if(response.IsSuccessful)
{
var result = JsonConvert.DeserializeObject<dynamic>(response.Content);
return result.access_token;
}
else
{
return "Fail";
}
After get the access token i create a request to server with the accesstoken i have:
public static string GetMailBox(string accessToken){
var client = new RestClient("https://graph.microsoft.com/v1.0/users/"your_email"/messages?$top=10");
client.Timeout = -1;
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer " + accessToken);
IRestResponse response = client.Execute(request);
if (response.IsSuccessful)
{
var result = JsonConvert.DeserializeObject<dynamic>(response.Content);
return result.value.ToString();
}
else
{
return "Fail";
}
You can read this document for create more request like example GetMailBox i put above Microsoft Graph API document

Graph API- Refresh Token- Bad Request 400

The goal it use Graph API to send an email.
I am able to get the Authorization token by using the below code - https://login.microsoftonline.com/Some_Tenant_ID/oauth2/v2.0/authorize?client_id=SOME_Client_ID&response_type=code&redirect_uri=https://localhost&response_mode=query&scope=offline_access%20user.read%20mail.read&state=12345
The scope is user.read and mail.send with offline access. Now from using this authorization code, I want to get the refresh token. From my understanding this should work without any problem but for some reason the code is breaking at this line var httpResponse = (HttpWebResponse)request.GetResponse(); and I not sure why.
The exception code error 400 Bad Request.
my console output.
Can any one help me here and is there another way to get the Access token and/or refresh token from Authorization token. the end goal is to send email from graph API.
string tokenUrl = "https://login.microsoftonline.com/myAppTenantID/oauth2/token";
//string tokenUrl = "https://login.microsoftonline.com/myAppTenantID/oauth2/v2.0/token"; I have tried this URL too
string grant_type= "authorization_code";
string ClientID = "MyAppClientID";
string Auth_Code = "My Auth Code";
string RedirectURI = "https://localhost";
string ClientSecret = "my App secret";
Dictionary<string, string> res_dic = null;
string TargetURL = String.Format(tokenUrl);
var request = (System.Net.HttpWebRequest)WebRequest.Create(TargetURL);
request.ContentType = "application/x-www-form-urlencoded";
string RefreshToken = null;
string requestBody = String.Format(#"client_id={0}&scope=user.read%20mail.read&code={1}&redirect_uri={2}&grant_type=authorization_code&client_secret={3}", ClientID, Auth_Code,RedirectURI, ClientSecret);
request.Method = "POST";
using (var streamwriter = new StreamWriter(request.GetRequestStream()))
{
Console.WriteLine("stage 0....");
streamwriter.Write(requestBody);
streamwriter.Flush();
streamwriter.Close();
}
try
{
Console.WriteLine("stage 1....");
//Console.WriteLine("prting response"+ (HttpWebResponse)request.GetResponse());
var httpResponse = (HttpWebResponse)request.GetResponse();
Console.WriteLine("Stage 2....");
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
Console.WriteLine("Stage 3");
string Result = streamReader.ReadToEnd();
string StatusCode = httpResponse.StatusCode.ToString();
res_dic = JsonConvert.DeserializeObject<Dictionary<string, string>>(Result);
}
}
catch (WebException ex)
{
Console.WriteLine("stage 4");
string ErrorMessage = ex.Message.ToString();
Console.WriteLine(ErrorMessage);
}
RefreshToken = res_dic["refresh_token"].ToString();
}
This is better for you to debug for full error message, there are many situations where this error occurs.
The scope in your code needs to add offline_access because refresh_token will be only provided if offline_access scope is requested.
You could use SDK. Code sample here:
string[] scopes = new string[] { "", "" };
IConfidentialClientApplication app = ConfidentialClientApplicationBuilder
.Create(clientId)
.WithRedirectUri(redirectUri)
.WithClientSecret(clientSecret)
.WithAuthority(authority)
.Build();
AuthorizationCodeProvider auth = new AuthorizationCodeProvider(app, scopes);
GraphServiceClient graphServiceClient = new GraphServiceClient(new DelegateAuthenticationProvider(async (requestMessage) => {
// Retrieve an access token for Microsoft Graph (gets a fresh token if needed).
var authResult = await app.AcquireTokenByAuthorizationCode(scopes, auth_code).ExecuteAsync();
// Add the access token in the Authorization header of the API request.
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
})
);
And this API is used for sending mail, you need to add Mail.Send permission first.
var message = new Message
{
Subject = "Meet for lunch?",
Body = new ItemBody
{
ContentType = BodyType.Text,
Content = "The new cafeteria is open."
},
ToRecipients = new List<Recipient>()
{
new Recipient
{
EmailAddress = new EmailAddress
{
Address = "fannyd#contoso.onmicrosoft.com"
}
}
},
CcRecipients = new List<Recipient>()
{
new Recipient
{
EmailAddress = new EmailAddress
{
Address = "danas#contoso.onmicrosoft.com"
}
}
}
};
var saveToSentItems = false;
await graphClient.Me
.SendMail(message,saveToSentItems)
.Request()
.PostAsync();

I want to implement sharepoint document search using C# api

I want to search sharepoint document using C# api call.
I am trying below code:
string URL = "http://server/_api/search/query?query_parameter=value&query_parameter=value";
System.Net.Http.HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "XXXXX", "XXXXXX"))));
using (client)
{
HttpResponseMessage httpResponseMessage = await client.GetAsync(URL);
HttpResponseMessage responsemMsgx = httpResponseMessage;
if (responsemMsgx.IsSuccessStatusCode)
{
}
}
But,i am have a doubt regarding URL below:
string URL = "http://server/_api/search/query?query_parameter=value&query_parameter=value";
Please help me with the sharepoint server and constructing the URL.
My expected output is something like JSON .
If you want to search documents, we can use the Search REST API below to achieve it.
/_api/search/query?querytext='IsDocument:True'
C# example:
string siteUrl = "http://sp2013/sites/team";
string searchQuery = "/_api/search/query?querytext='IsDocument:True'";//search all documents
var credential = new System.Net.NetworkCredential("username", "password", "domainname");
HttpClientHandler handler = new HttpClientHandler() { Credentials = credential };
HttpClient client = new HttpClient(handler);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Add("Accept", "application/json;odata=verbose");
client.DefaultRequestHeaders.Add("ContentType", "application/json;odata=verbose");
var result = client.GetAsync(siteUrl+searchQuery).Result;
var content = result.Content.ReadAsStringAsync().Result;
JObject jobj = JObject.Parse(content);
JArray jarr = (JArray)jobj["d"]["query"]["PrimaryQueryResult"]["RelevantResults"]["Table"]["Rows"]["results"];
foreach (JObject j in jarr)
{
JArray results = (JArray)j["Cells"]["results"];
var title = "";
var path = "";
foreach (JObject r in results)
{
if (r["Key"] != null)
{
if (r["Key"].ToString() == "Title")
{
title = r["Value"].ToString();
}
if (r["Key"].ToString() == "Path")
{
path = r["Value"].ToString();
}
}
}
Console.WriteLine(title + "|" + path);
}

Google OAuth2 get access token from refresh token with .net

I want to get access token from refresh token to send email in the server
But I get 400,"Bad Request" error.
here is the code I use on client side,
var CLIENT_ID = 'A';
var CLIENT_SECRET = 'B';
var DISCOVERY_DOCS = ["https://www.googleapis.com/discovery/v1/apis/gmail/v1/rest"];
var SCOPES = 'https://mail.google.com/';
function initClient() {
gapi.client.init({
clientId: CLIENT_ID,
discoveryDocs: DISCOVERY_DOCS,
scope: SCOPES
}).then(function() {
gapi.auth2.getAuthInstance().grantOfflineAccess().then(offline);
}, function(error) {
});
}
function offline(rtn) {
var refreshToken = rtn.code;
}
and here is the c# .net code I use on the server side to get access token
var secrets = new ClientSecrets
{
ClientId = "A",
ClientSecret = "B"
};
HttpClient xclient = new HttpClient();
xclient.BaseAddress = new Uri("https://www.googleapis.com");
var refreshMessage = new HttpRequestMessage(HttpMethod.Post, "/oauth2/v4/token")
{
Content = new FormUrlEncodedContent(new KeyValuePair<string, string>[]
{
new KeyValuePair<string, string>("client_id", secrets.ClientId),
new KeyValuePair<string, string>("client_secret", secrets.ClientSecret),
new KeyValuePair<string, string>("refresh_token", refreshToken),
new KeyValuePair<string, string>("grant_type", "refresh_token")
})
};
Task.Run(async () =>
{
var response = await xclient.SendAsync(refreshMessage);
if (response.IsSuccessStatusCode)
{
var tokenResponse = await response.Content.ReadAsStringAsync();
}
}).GetAwaiter().GetResult();
What could be wrong?

Getting error while posting login info on ASP.NET WEB API call

I am getting this exception while trying to do a post call on a ASP.NET Web API. I am calling this from a Windows Universal App:
Type
'<>f__AnonymousType0`3[System.String,System.String,System.String]'
cannot be serialized. Consider marking it with the
DataContractAttribute attribute.
Here is my code:
var loginData = new { grant_type = "password", username = name, password = pass };
var queryString = "grant_type = password, username = " + name + ", password = " + pass;
HttpClient httpClient = new HttpClient();
try
{
string resourceAddress = "http://localhost:24721/Token";
//int age = Convert.ToInt32(this.Agetxt.Text);
//if (age > 120 || age < 0)
//{
// throw new Exception("Age must be between 0 and 120");
//}
string postBody = Serialize(loginData);
httpClient.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage wcfResponse = await httpClient.PostAsync(resourceAddress,
new StringContent(queryString, Encoding.UTF8));
}
Best guess is, you're getting that error because the serializer you're using doesn't support anonymous types. I would recommend trying to use Json.Net, which handles them nicely. I believe you can include it from NuGet.
If you reference the library in your project then you could modify your code like so:
var loginData = new { grant_type = "password", username = name, password = pass };
HttpClient httpClient = new HttpClient();
try
{
string resourceAddress = "http://localhost:24721/Token";
string postBody = Newtonsoft.Json.JsonConvert.SerializeObjectloginData);
var content = new StringContent(postBody, Encoding.UTF8, "application/json");
httpClient.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage wcfResponse = await httpClient.PostAsync(resourceAddress, content);
}
I found the solution. i updated the post data as key value pair and it worked.
using (var client = new HttpClient())
{
string resourceAddress = "http://localhost:24721/Token";
var requestParams = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("username", name),
new KeyValuePair<string, string>("password", pass)
};
var requestParamsFormUrlEncoded = new FormUrlEncodedContent(requestParams);
var tokenServiceResponse = await client.PostAsync(resourceAddress, requestParamsFormUrlEncoded);
var responseString = await tokenServiceResponse.Content.ReadAsStringAsync();
var responseCode = tokenServiceResponse.StatusCode;
var responseMsg = new HttpResponseMessage(responseCode)
{
Content = new StringContent(responseString, Encoding.UTF8, "application/json")
};
return responseMsg;
}

Categories