Http Get Request for IpDBInfo using an IP Address - c#

I am working on a web application and it needs to track a location using an IP Address and I am new to sending requests to some APIs and getting a response from them. I was able to retrieve IP address of the user using Request.UserHostAddress
and was able to validate it using the following C# code
if (System.Text.RegularExpressions.Regex.IsMatch(ip, "[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}"))
{
string[] ips = ip.Split('.');
if (ips.Length == 4 || ips.Length == 6)
{
if (System.Int32.Parse(ips[0]) < 256 && System.Int32.Parse(ips[1]) < 256
& System.Int32.Parse(ips[2]) < 256 & System.Int32.Parse(ips[3]) < 256)
return true;
else
return false;
}
else
return false;
}
else
return false;
and I have got the API key and IP address required to request the following API
http://api.ipinfodb.com/v2/ip_query.php?key=[API KEY]&ip=[IP Address]&timezone=false
I know an HTTP GET REQUEST to the above would give me an XML response but not sure how to get started with the HTTP REQUEST in ASP.NET MVC using C#.
Can someone help me get started with this?

The response of IPInfoDB is a string like below:
OK;;74.125.45.100;US;United States;California;Mountain
View;94043;37.406;-122.079;-07:00
So we need to split into the various fields using C# codes below.
string key = "Your API key";
string ip = "IP address to check";
string url = "http://api.ipinfodb.com/v3/ip-city/?key=" + key + "&ip=" + ip;
HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(string.Format(url));
webReq.Method = "GET";
HttpWebResponse webResponse = (HttpWebResponse)webReq.GetResponse();
Stream answer = webResponse.GetResponseStream();
StreamReader response = new StreamReader(answer);
string raw = response.ReadToEnd();
char[] delimiter = new char[1];
delimiter[0] = ';';
string[] rawdata = raw.Split(delimiter);
ViewData["Response"] = "Country Code: " + rawdata[3] + " Country Name: " + rawdata[4] + " State: " + rawdata[5] + " City: " + rawdata[6];
response.Close();

Related

How to request an access token from OAuth using System.Net.Http? 401 Error

Context
I am developing a simple application that requires to receive List Data from a company Online SharePoint site. In order to make REST requests, I must first retrieve an access token from Microsoft's access control service. Despite attempting some tutorials and reading documentation, I am new to REST/HTTP am am failing to do so.
What have I tried?
Used SharePoint appregnew.aspx to register my app, and generate "Client ID" and "Client Secret" values. https://[sitename].sharepoint.com/_layouts/15/appregnew.aspx
Used Sharepoint appinv.aspx to authorize my app with read control and generate a "Tenant ID".
https://[sitename].sharepoint.com/_layouts/15/appinv.aspx
<AppPermissionRequests AllowAppOnlyPolicy="true">
<AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web" Right="Read"/>
</AppPermissionRequests>
Used SharePoint AppPrincipals.aspx to verify Tenant ID. https://[sitename].sharepoint.com/_layouts/15/AppPrincipals.aspx
Attempted several methods of formatting the request with the following being the latest:
Updated
// Variables removed for security
class Program
{
static void Main(string[] args)
{
WebRequest myWebRequest;
string stGetAccessTokenUrl = "https://accounts.accesscontrol.windows.net/{0}/tokens/OAuth/2";
string tenantID = "myTenantID";
string resourceID = "00000003-0000-0ff1-ce00-000000000000";
string stClientID = "myClientID";
string stClientSecret = "myClientSecret";
string stSiteDomain = "[myCompany].sharepoint.com";
// URL Format
stGetAccessTokenUrl = string.Format(stGetAccessTokenUrl, tenantID);
myWebRequest = WebRequest.Create(stGetAccessTokenUrl);
myWebRequest.ContentType = "application/x-www-form-urlencoded";
myWebRequest.Method = "POST";
// Add the below body attributes to the request
var postData = "grant_type=client_credentials";
postData += "&client_id=" + stClientID + "#" + tenantID;
postData += "&client_secret=" + stClientSecret;
postData += "&resource=" + resourceID + "/" + stSiteDomain + "#" + tenantID;
var data = Encoding.ASCII.GetBytes(postData);
using (var stream = myWebRequest.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)myWebRequest.GetResponse();
}
}
What doesn't work?
I receive a 401 Unauthorized error despite the app having been assigned permissions.
Any help would be greatly appreciated!
Apologies, I forgot to return to this question upon resolving the issue. Credit to "Michael Han" within the comments of his own answer.
Answer
By default, the SharePoint app-only permissions is disabled for the tenant. A tenant administrator must first run the following cmdlet in PowerShell:
Set-SPOTenant -DisableCustomAppAuthentication $false
This parameter supersedes all other privilege settings and must first be configured.
You could refer to this article to get the access token : https://social.technet.microsoft.com/wiki/contents/articles/51982.sharepoint-read-online-list-data-from-c-console-application-using-access-token.aspx
#region Get Access Token using TenantID and App secret ID & Password
// URL Format
//https://accounts.accesscontrol.windows.net/tenant_ID/tokens/OAuth/2 Jump
stGetAccessTokenUrl = string.Format(stGetAccessTokenUrl, tenantID);
myWebRequest = WebRequest.Create(stGetAccessTokenUrl);
myWebRequest.ContentType = "application/x-www-form-urlencoded";
myWebRequest.Method = "POST";
// Add the below body attributes to the request
/*
* grant_type client_credentials client_credentials
client_id ClientID#TenantID
client_secret ClientSecret
resource resource/SiteDomain#TenantID resourceid/abc.sharepoint.com#tenantID
*/
var postData = "grant_type=client_credentials";
postData += "&client_id=" + stClientID +"#" +tenantID;
postData += "&client_secret=" + stClientSecret;
postData += "&resource=" + resourceID + "/" + stSiteDomain + "#" + tenantID;
var data = Encoding.ASCII.GetBytes(postData);
using (var stream = myWebRequest.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)myWebRequest.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
string[] stArrResponse = responseString.Split(',');
//get the access token and expiry time ,etc
foreach(var stValues in stArrResponse)
{
if(stValues.StartsWith("\"access_token\":"))
{
//Console.WriteLine(" Result => " + stValues);
accessToken = stValues.Substring(16);
//Console.WriteLine(" Result => " + accessToken);
accessToken = accessToken.Substring(0,accessToken.Length-2);
// Console.WriteLine(" Result => " + accessToken);
}
}

C# does not receive any response values from Jenkins

I'm calling Jenkins jobs from C# using the WebClient class and I'm not receiving any response even though the Jenkins job is triggering and executing properly. I need to read the headers to get the queue number and things like that, so I'm confused as to why this is happening. Below is my code, which works just fine except for "response" is always an empty string; not null, just an empty string:'
'
using (var wb = new WebClient())
{
string url = "http://url:8080/job/CloudTeam/job/Azure/job/Create-Azure-VM/buildWithParameters";
string queryString = "HOSTNAME=" + virtualMachine.Hostname + "&IPADDRESS=" + virtualMachine.IPAddress + "&RESOURCEGROUP=" + virtualMachine.ResourceGroup + "&STORAGEACCOUNT=" + virtualMachine.StorageAccount + "&BASEIMAGE=" + virtualMachine.BaseImage;
string password = "password";
string username = "user";
string basicAuthToken = Convert.ToBase64String(Encoding.Default.GetBytes(username + ":" + password));
wb.Headers["Authorization"] = "Basic " + basicAuthToken;
wb.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
wb.Headers.Add("user", "user:password");
string response = wb.UploadString(url, queryString);
return response; <-- always an empty string
}
'

How do I compose the Firebase request so that I can broadcast 100 notification to Mobile Devices in single request?

I want to send a notification to multiple device in single FCM request. My notification text is same for all devices.
I would like to send notification to mobile devices in a batch of 100 per request. I am using c# asmx service.
Below is my code.
string regid="c_Z5yRoj4TY:APA91bGry2g_CIA1xaRy_LscxOvFX6YHqasKA96TjpG6yi1yytNyM5rtGL6DgxjGMSE5c74d7VdSL6W8zxO1ixVMlpVMwdgcrsGUWV0VfdbddC2XD","c_Z5yRoj4TY:APA91bGry2g_CIA1xaRy_LscxOvFX6YHqasKA96TjpG6yi1yytNyM5rtGL6DgxjGMSE5c74d7";
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create("https://fcm.googleapis.com/fcm/send");
httpWebRequest.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
httpWebRequest.Method = "POST";
String collaps_key = "Score_update";
string json = "collapse_key=abcd" + "&data.header=cricket&registration_id=" + regId + "&data.notificationId=" + notificationId + "&data.message=" + msg;
httpWebRequest.Headers.Add(string.Format("Authorization: key={0}", applicationID));
httpWebRequest.Headers.Add(string.Format("Sender: key={0}", SENDER_ID));
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
//Console.WriteLine(json);
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
using (HttpWebResponse httpResponse = (HttpWebResponse)httpWebRequest.GetResponse())
{
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
Console.WriteLine(result);
retmsgid = result.ToString();
if (retmsgid.Trim() != "")
{
ResponceString = result.ToString();
string[] msgsplits = retmsgid.Split(',');
string[] msg1 = msgsplits[0].ToString().Split(':');
ReturnMessageId = msg1[1].ToString();
}
else
{
ReturnMessageId = "0";
}
}
httpResponse.Close();
httpResponse.Dispose();
httpWebRequest = null;
}
}
In order to send to specific multiple registration devices, you'll have to make use of the registration_ids parameter:
This parameter specifies the recipient of a multicast message, a message sent to more than one registration token.
The value should be an array of registration tokens to which to send the multicast message. The array must contain at least 1 and at most 1000 registration tokens. To send a message to a single device, use the to parameter.
In your code, you were using registration_id which I think is invalid. It should be registration_ids:
string json = "collapse_key=abcd" + "&data.header=cricket&registration_ids=" + regIds + "&data.notificationId=" + notificationId + "&data.message=" + msg;
-- regIds here is an Array of Strings that contain your registration tokens.
Some previous posts that may also help (see the OPs code snippets):
FCM (Firebase Cloud Messaging) Send to multiple devices
How to send multiple Firebase Cloud Message with C#?

Twitch TV OAuth Login In C#

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?

Calling Google API after having access Token to fetch profiledata

I am very new to OAuth Arena and Google ApI but what I am trying to achieve here is very simple.
User Clicks on Google Connect button and my webservice should be able to get all the user Profile Info from Google server:
I have already written code to get AccessToken(I am yet to test it) but assuming that is working fine, now how should I ask Google API to give me user profile? I do see static function called Get Contacts in GoogleConsumer Class but I do not see any option to get profiledata. May be there is something that I am missing?
Here is my code using which i am getting accessToken:
IConsumerTokenManager tokenManager =
new LocalTokenManager(consumerKey,consumerSecret);
var googleConsumer =
new WebConsumer(GoogleConsumer.ServiceDescription, tokenManager);
var tokenResult = googleConsumer.ProcessUserAuthorization();
return tokenResult.AccessToken;
Now, how do I get user profile out of it?
Once you have your Access_Token (access type offline; and scope/permission is set so you can get user information), you can try the following (not tested, please let me know if any errors occur):
string userInfo = "";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(action);
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
StreamReader sr = new StreamReader(resp.GetResponseStream());
userInfo = "https://www.googleapis.com/oauth2/v1/userinfo?access_token=" + "YOUR_ACCESSTOKEN";
sr.Close();
JObject jsonResp = JObject.Parse(userInfo);
string info="";
info += "<h3>" + jsonResp.Root["name"] + "</h3>";
info += "<img src='" + jsonResp.Root["picture"] + "' width='120'/><br/>";
info += "<br/>ID : " + jsonResp.Root["id"];
info += "<br/>Email : " + jsonResp.Root["email"];
info += "<br/>Verified_email : " + jsonResp.Root["verified_email"];
info += "<br/>Given_name : " + jsonResp.Root["given_name"];
info += "<br/>Family_name : " + jsonResp.Root["family_name"];
info += "<br/>Link : " + jsonResp.Root["link"];
info += "<br/>Gender : " + jsonResp.Root["gender"];
Response.Write(info);
Flow : Requesting the google userinfo url with the access token, get the response and displaying the information.
let me know what do you think about accessing profile's google info with their GET method, described here https://developers.google.com/+/api/latest/people/get?
This is my C# example.
string urlGoogle = "https://www.googleapis.com/plus/v1/people/me";
HttpWebRequest client = HttpWebRequest.Create(urlGoogle) as HttpWebRequest;
client.Method = "GET";
client.Headers.Add("Authorization", "Bearer " + accessToken);
using (HttpWebResponse response = (HttpWebResponse)client.GetResponse())
{
using (Stream dataStream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(dataStream))
{
if (response.StatusCode == HttpStatusCode.OK)
{
var json = new JavaScriptSerializer();
var data = json.Deserialize<IDictionary<string, object>>(reader.ReadToEnd());
//....... here in data you have all json fields for the profile

Categories