Get request for my Paypal AccessToken - c#

I am trying to get my access token of paypal.
I have the next parameters: EndPoint, Client Id, secret, api username, api signature, api password, application Id.
should I need a paypal client in order to do it?
I followed this link: https://developer.paypal.com/docs/integration/direct/make-your-first-call/
and tried:
private string getAccessToken() {
var ppClient; // = new paypalClient(); // create a paypal client
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("Accept", "application/json");
parameters.Add("Accept-Language", "en_US");
parameters.Add("grant_type", "client_credentials");
var result = ppClient.Get("https://api.sandbox.paypal.com/v1/oauth2/token", parameters);
string accessToken = result["access_token"];
return accessToken;
}
thank you all!

I would recomend using RestSharp (just grab the NuGet package): -
if (ServicePointManager.SecurityProtocol != SecurityProtocolType.Tls12) ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; // forced to modern day SSL protocols
var client = new RestClient(payPalUrl) { Encoding = Encoding.UTF8 };
var authRequest = new RestRequest("oauth2/token", Method.POST) {RequestFormat = DataFormat.Json};
client.Authenticator = new HttpBasicAuthenticator(clientId, secret);
authRequest.AddParameter("grant_type","client_credentials");
var authResponse = client.Execute(authRequest);

Came to this a little late, but ran into similar problem. In the end I had to use a "Basic" authentication implementation to get the details back from PayPal. This is my Token Collector class. The Only thing you really need to do is substitute my PayPal options injection with your 2 paypal client_Id and Secret strings generated in your paypal set up.
Ignore my AccessToken return type, its just a PoCo I made up and the ReadToObject is just a simple deserializer using newtonsoft.
The real good stuff is returned to the 'result' string.
Hope this helps!
public sealed class PaymentTokenServer : IPaymentTokenServer
{
private readonly List<KeyValuePair<string, string>> tokenServerPairs = new List<KeyValuePair<string, string>>();
private PayPalOptions payPalOptions;
public PaymentTokenServer(IOptions<PayPalOptions> paypalOptions)
{
this.payPalOptions = paypalOptions.Value;
this.tokenServerPairs.Add(new KeyValuePair<string, string>("grant_type", "client_credentials"));
}
public AccessToken GetToken()
{
var content = new FormUrlEncodedContent(this.tokenServerPairs);
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(this.payPalOptions.TokenServerUrl);
client.DefaultRequestHeaders.AcceptLanguage.Add( new StringWithQualityHeaderValue("en_US"));
var base64String = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{this.payPalOptions.ClientId}:{this.payPalOptions.Secret}"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", base64String);
var response = client.PostAsync("", content).Result;
var result = response.Content.ReadAsStringAsync().Result;
return result.ReadToObject<AccessToken>();
}
}
}

Related

Re-generating Postman request from C#

I'm having an issue creating a POST request from C# to generate a token. There's nothing wrong with the service because I can consume it using Postman.
Can someone help my out.
Following my coding. Every time I get a 403 error.
public async Task<string> LoginAsync(string userName, string password)
{
try
{
var keyValues = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("grant_type", "client_credentials")
};
var request = new HttpRequestMessage(HttpMethod.Post, login_url);
request.Content = new FormUrlEncodedContent(keyValues);
var client = new HttpClient();
var authenticationBytes = System.Text.Encoding.ASCII.GetBytes("----------username-------- : ----------pwd----------");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(authenticationBytes));
//request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(authenticationBytes));
var response = await client.SendAsync(request);
var jwtResponse = await response.Content.ReadAsStringAsync(); // contains access token
JObject jwtDynamic = JsonConvert.DeserializeObject<dynamic>(jwtResponse);
accessToken = jwtDynamic.Value<string>("access_token");
Debug.WriteLine(jwtResponse);
}
catch (Exception e)
{
Console.WriteLine(e);
}
return accessToken;
}
Following are the screenshots of Postman.
Thanks a lot.
you can use generating code from postman using RestSharp Library for .Net as you can see by clicking on code button below in the picture .
best regards

write a http post request to bot framework running on localhost

I have a bot running on http://localhost:3978/api/messages.
Instead of debugging it using an emulator, can I go about using a http post request to the messaging endpoint of the bot?
If so, how do I go about doing it?
I am using c# microsoft bot framework, and I am new to this application.
I do not want to use any channels or DirectLine api, just using Httpclient.
You can do this with C# using code similar to below. Note that you would have to construct an Activity to send by setting the appropriate properties for your needs, which is not included in this code.
//make a call to get an auth token
string token;
using (var client = new WebClient())
{
var values = new NameValueCollection();
values["grant_type"] = "client_credentials";
values["client_id"] = "YOUR APP ID";
values["client_secret"] = "NcOXRwb51joibEfzUuNE04u";
values["scope"] = "YOUR APP ID/.default";
var response =
client.UploadValues("https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token", values);
var responseString = Encoding.Default.GetString(response);
var result = JsonConvert.DeserializeObject<ResponseObject>(responseString);
token = result.access_token;
}
//you will need to adjust this value for your project.
//this example for a proxy project so the service url here is
//just an arbitrary endpoint I was using to send activities to
activity.ServiceUrl = "http://localhost:4643/api/return";
var jsonActivityAltered = JsonConvert.SerializeObject(activity);
using (var client = new WebClient())
{
client.Headers.Add("Content-Type", "application/json");
client.Headers.Add("Authorization", $"Bearer {token}");
try
{
var btmResponse = client.UploadString("http://localhost:3971/api/messages", jsonActivityAltered);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
Have you tried using something like postman? (it's free and easy to use)
https://www.getpostman.com/
You can also write scripts in postman
otherwise you can just go to the endpoint of your API in the browser
http://localhost:3978/api/
I see you mentioned you wanted to make a console application.
You could do that. I'd suggest using postman though.
Here is an example of sending a file as well as some querystring data and Authentication using a Bearer token.
Sorry it may not be exact. Had to do a bit of copy pasting/deleting from some code examples if have
using (HttpClient client = new HttpClient())
{
JObject jsonModel = new JObject();
client.BaseAddress = new Uri("http://localhost:3978/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AuthToken);
using (var multipartFormDataContent = new MultipartFormDataContent())
{
var values = new[]
{
new KeyValuePair<string, string>("firstname", lastname),
new KeyValuePair<string, string>("lastname", lastname),
new KeyValuePair<string, string>("payloadFile", FileName)
};
foreach (var keyValuePair in values)
{
multipartFormDataContent.Add(new StringContent(keyValuePair.Value),
String.Format("\"{0}\"", keyValuePair.Key));
}
ByteArrayContent fileContent = new ByteArrayContent(File.ReadAllBytes(HttpContext.Current.Server.MapPath("~/uploads/output/" + FileName)));
string FullxmlString = File.ReadAllText(Path.Combine(HttpContext.Current.Server.MapPath("~/uploads/output/" + FileName)));
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("payloadFile") { FileName = "payloadFile" };
multipartFormDataContent.Add(fileContent);
HttpResponseMessage response = client.PostAsync("api/message", multipartFormDataContent).Result;
string returnString = response.Content.ToString();
using (HttpContent content = response.Content)
{
string res = "";
Task<string> result = content.ReadAsStringAsync();
res = result.Result;
}
}
}

PowerBI and Azure AD Headless Login

I am trying to embed PowerBI dashboards into my customer MVC portal. My customers don't have AAD accounts, so they can't login to Live when they come to the website, they log into my MVC website with individual authority.
I have registered my App on PowerBI/AAD and have the ClientID and Secret. I make the call to AAD and get an Authorization Code which I then use to get an Athentication Token which the is returned successfully.
When ever I use the access token to get a dashboard it is continually rejected with a 403 Forbidden.
I have gone through all the samples from Microsoft, but they require a user login prompt. I have reviewed the ADAL2.0 code which refers to the AcquireToken Method, but this was deprecated in ADAL3 and replaced with AcquireTokenAsync which has different parameters and I am using this in my example below.
Here is the function to get the token:
protected AuthenticationResult GetAccessToken()
{
string pBiUser = Properties.Settings.Default.PowerBIUser;
string pBiPwd = Properties.Settings.Default.PowerBIPwd;
string pBiClientId = Properties.Settings.Default.PowerBIClientId;
string pBiSecret = Properties.Settings.Default.PowerBIClientSecret;
TokenCache TC = new TokenCache();
ClientCredential CC = new ClientCredential(pBiClientId,pBiSecret);
string AU = Properties.Settings.Default.PowerBIAuthority;
Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext authenticationContext
= new Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext(AU, TC);
AuthenticationResult result = authenticationContext.AcquireTokenAsync("https://analysis.windows.net/powerbi/api"
,CC).Result;
if (result == null)
{
throw new InvalidOperationException("Failed to obtain the PowerBI token");
}
return result;
}
I then take the result token and call. The response receives the 403:
protected PBIDashboards GetDashboards(AuthenticationResult authResult)
{
PBIDashboards pbiDashboards = new PBIDashboards();
var baseAddress = new Uri("https://api.powerbi.com");
using (var httpClient = new System.Net.Http.HttpClient {BaseAddress = baseAddress})
{
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("authorization",
"Bearer " + authResult.AccessToken);
using (**var response** = httpClient.GetAsync("v1.0/myorg/dashboards").Result)
{
string responseData = response.Content.ReadAsStringAsync().Result;
//Deserialize JSON string
pbiDashboards = JsonConvert.DeserializeObject<PBIDashboards>(responseData);
if (pbiDashboards != null)
{
var gridViewDashboards = pbiDashboards.value.Select(dashboard => new
{
Id = dashboard.id,
DisplayName = dashboard.displayName,
EmbedUrl = dashboard.embedUrl
});
}
}
}
return pbiDashboards;
}
Based on the error message(403), the issue is relative to the permission.
And AFAIK the is no such permission we can use when we acquire the access token using the client credentials flow for the Power BI REST. You can refer the permission for the figure below:
To get the token for the Power BI REST without user interaction, we can use the Resource owner password credentials flow. And you can use the 3rd party library PowerBI.Api.Client which already implement this.
After a lot of research, you can make a direct AJAX call to get the token:
private async Task<string> GetAccessToken()
{
string pBiUser = Properties.Settings.Default.PowerBIUser;
string pBiPwd = Properties.Settings.Default.PowerBIPwd;
string pBiClientId = Properties.Settings.Default.PowerBIClientId;
string pBiSecret = Properties.Settings.Default.PowerBIClientSecret;
string pBITenant = Properties.Settings.Default.PowerBITenantId;
string tokenEndpointUri = "https://login.microsoftonline.com/"+pBITenant+"/oauth2/token";
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("username", pBiUser),
new KeyValuePair<string, string>("password", pBiPwd),
new KeyValuePair<string, string>("client_id", pBiClientId),
new KeyValuePair<string, string>("client_secret", pBiSecret),
new KeyValuePair<string, string>("resource", "https://analysis.windows.net/powerbi/api")
});
using (var client = new HttpClient())
{
HttpResponseMessage res = client.PostAsync(tokenEndpointUri, content).Result;
string json = await res.Content.ReadAsStringAsync();
AzureAdTokenResponse tokenRes = JsonConvert.DeserializeObject<AzureAdTokenResponse>(json);
return tokenRes.AccessToken;
}
}
Once you have the string AccessToken, you can then call the Dashboards request.
protected PBIDashboards GetDashboards(string token)
{
PBIDashboards pbiDashboards = new PBIDashboards();
var baseAddress = new Uri("https://api.powerbi.com");
using (var httpClient = new System.Net.Http.HttpClient {BaseAddress = baseAddress})
{
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("authorization",
"Bearer " + token);
using (var response = httpClient.GetAsync("v1.0/myorg/dashboards").Result)
{
string responseData = response.Content.ReadAsStringAsync().Result;
//Deserialize JSON string
pbiDashboards = JsonConvert.DeserializeObject<PBIDashboards>(responseData);
if (pbiDashboards != null)
{
var gridViewDashboards = pbiDashboards.value.Select(dashboard => new
{
Id = dashboard.id,
DisplayName = dashboard.displayName,
EmbedUrl = dashboard.embedUrl
});
}
}
}
return pbiDashboards;
}
This will provide you the list of dashboards and the dashboard Id to call the PowerBI API to build the embeded page in Javascript. I used hidden input fields to store the access token and embed URL to pass over to the Javascript call.
// check if the embed url was selected
var embedUrl = document.getElementById('embed').value;
if (embedUrl === "")
return;
// get the access token.
accessToken = document.getElementById('token').value;
// Embed configuration used to describe the what and how to embed.
// This object is used when calling powerbi.embed.
// You can find more information at https://github.com/Microsoft/PowerBI-JavaScript/wiki/Embed-Configuration-Details.
var config = {
type: 'dashboard',
accessToken: accessToken,
embedUrl: embedUrl
};
// Grab the reference to the div HTML element that will host the dashboard.
var dashboardContainer = document.getElementById('dashboard');
// Embed the dashboard and display it within the div container.
var dashboard = powerbi.embed(dashboardContainer, config);

Windows.Web.Http.HttpClient: Receiving cookies and save them

I need some help with the new Windows.Web.Http.HttpClient Class. I am writing my first WP8.1 App right now and it drives me crazy. I am logging into a website like this:
var values = new Dictionary<string, string>();
values.Add("login_username", _username);
values.Add("login_password", _password);
values.Add("login_lifetime", "36000");
var parameters = new HttpFormUrlEncodedContent(values);
var response = await Forum.Http.PostAsync(new Uri("http://foo.bar.xyz"), parameters);
var buffer = await response.Content.ReadAsBufferAsync();
byte[] byteArray = buffer.ToArray();
string content = Encoding.UTF8.GetString(byteArray, 0, byteArray.Length);
if (content.Contains("Wrong password/user name"))
{
return false;
}
return true;
And this works pretty fine. My HttpClient is a static field, like this:
public static HttpBaseProtocolFilter Filter = new HttpBaseProtocolFilter();
public static HttpClient Http = new HttpClient(Filter);
The login works just fine, but it doesn't save the cookies the website sends after logging in. How can I save them and can I send them to the website on every GetAsync()?
You can use HttpClientHandler instead of HttpBaseProtocolFilter. If you must use HttpBaseProtocolFilter, then there is a read-only CookieManager property of type HttpCookieManager that could help you.
Here's an example using HttpClientHandler:
public static CookieContainer Cookies = new CookieContainer();
public static HttpClientHandler HttpClientHandler = new HttpClientHandler() { CookieContainer = Cookies };
public static HttpClient Http = new HttpClient(HttpClientHandler);
After your PostAsync() call returns, you can extract the cookies
var uri = new Uri("http://foo.bar.xyz");
var response = await Forum.Http.PostAsync(uri, parameters);
IEnumerable<Cookie> responseCookies = Cookies.GetCookies(uri).Cast<Cookie>();
foreach (Cookie cookie in responseCookies) {
Console.WriteLine(cookie.Name + ": " + cookie.Value);
}
If you'd like to re-use a cookie from the initial request, you can create your own CookieContainer and copy the cookie from the response cookies. Or - you could also add a hard-coded cookie like this:
Cookies.Add(new HttpCookie("Name", "Value") { Domain="http://foo.bar.xyz" });

C# HttpClient POST request

i'm trying to create a POST request and I can't get it to work.
this is the format of the request which has 3 params, accountidentifier / type / seriesid
http://someSite.com/api/User_Favorites.php?accountid=accountidentifier&type=type&seriesid=seriesid
and this is my C#
using (var httpClient = new HttpClient())
{
httpClient.BaseAddress = new Uri("http://somesite.com");
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("accountidentifier", accountID),
new KeyValuePair<string, string>("type", "add"),
new KeyValuePair<string, string>("seriesid", seriesId),
});
httpClient.PostAsync("/api/User_Favorites.php", content);
}
Any ideas?
IMO, dictionaries in C# are very useful for this kind of task.
Here is an example of an async method to complete a wonderful POST request:
public class YourFavoriteClassOfAllTime {
//HttpClient should be instancied once and not be disposed
private static readonly HttpClient client = new HttpClient();
public async void Post()
{
var values = new Dictionary<string, string>
{
{ "accountidentifier", "Data you want to send at account field" },
{ "type", "Data you want to send at type field"},
{ "seriesid", "The data you went to send at seriesid field"
}
};
//form "postable object" if that makes any sense
var content = new FormUrlEncodedContent(values);
//POST the object to the specified URI
var response = await client.PostAsync("http://127.0.0.1/api/User_Favorites.php", content);
//Read back the answer from server
var responseString = await response.Content.ReadAsStringAsync();
}
}
You can try WebClient too. It tries to accurately simulate what a browser would do:
var uri = new Uri("http://whatever/");
WebClient client = new WebClient();
var collection = new Dictionary<string, string>();
collection.Add("accountID", accountID );
collection.Add("someKey", "someValue");
var s = client.UploadValuesAsync(uri, collection);
Where UploadValuesAsync POSTs your collection.

Categories

Resources