HttpWebRequest.RequestURI.Scheme Always Returning 'https' - c#

static void Main()
{
Console.WriteLine("10504: " + TestURL("business.lynchburgchamber.org"));
Console.WriteLine("Google: " + TestURL("google.com"));
Console.ReadKey();
}
static string TestURL(string baseURL)
{
try
{
string httpsURL = "https://" + baseURL;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(httpsURL);
return request.RequestUri.Scheme;
}
catch
{
string httpURL = "http://" + baseURL;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(httpURL);
return request.RequestUri.Scheme;
}
}
I am testing urls to see if they are either http or https. My idea was to use an HttpWebRequest to check if the https request goes through, and if it fails go for the http. My problem is that if I go to https://business.lynchburgchamber.org in my browser if fails to connect, but my web request in my program returns https. Anyone have a better way to do this?

Your problem is, that you are not issuing the request, your just creating and instance to do the request.
So what you actually have to do is this:
static string TestURL(string baseURL)
{
try
{
string httpsURL = "https://" + baseURL;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(httpsURL);
request.Method = "GET";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
return request.RequestUri.Scheme;
}
catch
{
string httpURL = "http://" + baseURL;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(httpURL);
//request.Method = "GET";
//HttpWebResponse response = (HttpWebResponse)request.GetResponse();
return request.RequestUri.Scheme;
}
}
The second issuing could be also done, but as I think you are intending to check if a site has https, this would be misleading.
But keep in mind that it will return http if there is no internet connection!

Add a Request.GetResponse to really check if you have a Response from the URL:
var rt=request.GetResponse();
To be really sure, after this you can check the port
rt.ResponseUri.Port
if it returns 80 it must be Http,443 for https

Related

400 vs 401 http responses : which one is evaluated/returned first?

I have been trying to make a post request with C# using Webclient. I was getting 400 bad request.When I adjusted the headers, and added authorization to it,I started getting 401 authorization error.Now i commented out the authorization, 400 bad request is back. So my question is: when it was returning 400, does it mean the server authenticated me and that something might be wrong with my json or can 400 be returned even before authentication is done? Below is my code.
public static string Post(string json, string encoded){
try{
string url = "https://blah/rest/api/blah";
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var client = new WebClient();
client.Encoding = Encoding.UTF8;
IWebProxy wp = WebRequest.DefaultWebProxy;
wp.Credentials = CredentialCache.DefaultCredentials;
client.Proxy = wp;
//client.Headers[HttpRequestHeader.Authorization] = "Basic " + encoded;
client.Headers[HttpRequestHeader.ContentType] = "application/json";
client.Headers[HttpRequestHeader.Accept] = "application/json";
var response = client.UploadString(url, "POST",json);
return response
}
catch(Exception e){
return e
}
}

how to know given website is https protected or not in C#

how to Verify where website is using https, a secure communication protocol/not.
like if i give www.facebook.com it should show https protected or not.im getting error in second line.im getting false even though site is https
checkSecured();
private void checkSecured()
{
string url = txturl.Text.Trim();
var uri = new Uri("https://www.facebook.com");
var requestType = uri.Scheme;
var value= HttpContext.Current.Request.IsSecureConnection;
}
there are many sites which works on both http and https, some works on http and some on https.
So in your url check twice
1) If http://+url is valid or not
2) if https://+url is valid or not.
Then you can get the result.
private bool RemoteFileExists(string url)
{
try
{
//Creating the HttpWebRequest
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
//Setting the Request method HEAD, you can also use GET too.
request.Method = "HEAD";
//Getting the Web Response.
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
//Returns TRUE if the Status code == 200
response.Close();
return (response.StatusCode == HttpStatusCode.OK);
}
catch
{
//Any exception will returns false.
return false;
}
}
from: C# How can I check if a URL exists/is valid?
You can use the below line of code to check if the connection is secured or not.
HttpContext.Current.Request.IsSecureConnection

401 Unauthorized when calling Stormpath REST API with WebRequest object?

I am using Stormpath for my authentication service. I call the RestAPI of Stormpath by using HttpWebRequest.
I am also using HttpWebRequest to call the RestAPI but it does not work.
private void BtnGetResetApiClick(object sender, EventArgs e)
{
var username = "aaaa";
var password = "bbbb";
ServicePointManager.ServerCertificateValidationCallback = Callback;
var request = WebRequest.Create("https://api.stormpath.com/v1/tenants/current") as HttpWebRequest;
request.UserAgent = ".NET SDK";
request.Method = "GET";
request.Accept = "*/*";
var data = string.Format("{0}:{1}", username, HttpUtility.HtmlEncode(password));
var token = Convert.ToBase64String(Encoding.UTF8.GetBytes(data));
string authHeader = string.Format("Basic {0}", token);
request.Headers.Add("Authorization", authHeader);
request.ServerCertificateValidationCallback = Callback;
using (var response = request.GetResponse())
{
var stream = response.GetResponseStream();
if (stream != null)
{
var streamReader = new StreamReader(stream);
var str = streamReader.ReadToEnd();
streamReader.Close();
stream.Close();
}
}
}
private bool Callback(object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true;
}
When calling:
var response = request.GetResponse()
I got an exception:
An unhandled exception of type 'System.Net.WebException' occurred in System.dll The remote server returned an error: (401) Unauthorized.
Can you help me to see if my code has something wrong?
Update - use the SDK, it's much easier!
If you're calling the Stormpath API from C# frequently, don't bother with writing requests by hand. Use the Stormpath .NET SDK instead. I'm the author. :)
Install it using install-package Stormpath.SDK from the Package Manager Console. Then, create an IClient object:
// In a production environment, you'll want to load these from
// environment variables or a secure file, instead of hardcoding!
var apiKey = ClientApiKeys.Builder()
.SetId("Your_Stormpath_API_key_ID")
.SetSecret("Your_Stormpath_API_key_secret")
.Build();
var client = Clients.Builder()
.SetApiKey(apiKey)
.Build();
Getting the tenant info is now just a simple call:
var tenant = await client.GetCurrentTenantAsync();
Console.WriteLine($"Current tenant is: {tenant.Name}");
If you really want to make raw requests, you can still do that! I'll explain below.
Constructing the Authorization header
A 401 Unauthorized response means that the API was not able to find a valid Authorization header in your request. To authenticate correctly, you need two things:
An authorization payload in the format apiKeyID:apiKeySecret
An Authorization header with value: Basic base64(payload)
Here's how to construct the complete header:
// API_KEY_ID and API_KEY_SECRET populated elsewhere
var authPayload = string.Format("{0}:{1}", API_KEY_ID, API_KEY_SECRET);
var authPayloadEncoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(authPayload));
request.Headers.Add(HttpRequestHeader.Authorization, "Basic " + authPayloadEncoded);
You don't need the ServerCertificateValidationCallback = Callback stuff. With the above header, the request will be seen by the API as a valid request (assuming your API Key ID and Secret are correct, of course).
Redirection handling
One thing to watch out for (this tripped me up at first!) is that WebRequest will follow HTTP 302 redirects automatically, but will not apply the existing headers to the new request.
The solution is to disable redirect following:
request.AllowAutoRedirect = false;
This means you'll have to handle 302 responses yourself, but it's the only way to correctly apply the Authorization header to each request.
Working example
I created a simple working example in this gist. Since I'll be creating requests multiple times, I wrote a helper function:
private static HttpWebRequest BuildRequest(string method, string uri)
{
var request = WebRequest.Create(uri) as HttpWebRequest;
request.UserAgent = "dotnet/csharp web-request";
request.Method = method;
request.ContentType = "application/json";
// Important, otherwise the WebRequest will try to auto-follow
// 302 redirects without applying the authorization header to the
// subsequent requests.
request.AllowAutoRedirect = false;
// Construct HTTP Basic authorization header
var authPayload = string.Format("{0}:{1}", API_KEY_ID, API_KEY_SECRET);
var authPayloadEncoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(authPayload));
request.Headers.Add(HttpRequestHeader.Authorization, "Basic " + authPayloadEncoded);
return request;
}
And a simple console app to demonstrate getting the current tenant URL and name:
// Get these from the Stormpath admin console
private static string API_KEY_ID = "Your_Stormpath_API_key_ID";
private static string API_KEY_SECRET = "Your_Stormpath_API_key_secret";
static void Main(string[] args)
{
// First, we need to get the current tenant's actual URL
string tenantUrl = null;
var getCurrentTenantRequest = BuildRequest("GET", "https://api.stormpath.com/v1/tenants/current");
try
{
using (var response = getCurrentTenantRequest.GetResponse())
{
tenantUrl = response.Headers["Location"];
}
}
catch (WebException wex)
{
Console.WriteLine("Request failed. {0}", wex.Message);
throw;
}
// Now that we have the real tenant URL, get the tenant info
string tenantData = null;
var getTenantInfoRequest = BuildRequest("GET", tenantUrl);
try
{
using (var response = getTenantInfoRequest.GetResponse())
using (var responseStream = response.GetResponseStream())
using (var reader = new StreamReader(responseStream))
{
tenantData = reader.ReadToEnd();
}
}
catch (WebException wex)
{
Console.WriteLine("Request failed. {0}", wex.Message);
throw;
}
// Use JSON.NET to parse the data and get the tenant name
var parsedData = JsonConvert.DeserializeObject<Dictionary<string, object>>(tenantData);
Console.WriteLine("Current tenant is: {0}", parsedData["name"]);
// Wait for user input
Console.ReadKey(false);
}
The code is pretty verbose because we're making raw requests to the API. Again, if you're making requests frequently, use the SDK instead!

Using the TeamViewer API

I am looking to create a C# application that will report on the connections that we make to customers. I am looking into the TeamViewer API, but I cannot get the code below to authenticate:
string accessToken = "xxxxxxxxxxxxxxxxxxx";
string apiVersion = "v1";
string tvApiBaseUrl = "https://webapi.teamviewer.com";
string address = tvApiBaseUrl + "/api/" + apiVersion + "/reports/connections";
try
{
// Create the web request
HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
request.Headers.Add("Bearer", accessToken);
request.Method = "GET";
WebResponse webResp = request.GetResponse();
}
catch (Exception)
{
// Do nothing for now
}
Use fiddler and make sure your requests include the authorization header.
All API requests need to include the "Authorization" header if the API function requires an access token.
Example
GET /api/v1/users HTTP/1.1
Host: webapi.teamviewer.com
Authorization: Bearer 54213-2YotnFZFEjr1zCsicMWp
Also examine what they are sending you back, it may provide a clue.
UPDATE
Try this change
request.Headers.Add("Authorization", "Bearer " + accessToken);

How to redirect a WCF to an external URL (Google AdWords Sign In) and handle the response?

I am building a WCF that encapsulates Google OAuth 2.0.
The plan: Client calls WCF endpoint which then redirects to the Google Sign In page for user authentication. On successful authentication, Google kicks back to the redirect URI and returns the Access Token in the response.
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class AdWordsOAuthService : IOAuthService
{
public string AuthenticateAndGetRefreshToken()
{
string refreshToken = string.Empty;
try
{
AuthenticateUser();
}
catch (Exception ex)
{
throw;
}
return refreshToken;
}
private void AuthenticateUser()
{
// build the SOAP header here...
string authUrl = "https://accounts.google.com/o/oauth2/auth"; //redirect to this url
string postData = "response_type=code"
+ "&client_id=" + HttpUtility.UrlEncode("9999999999999.apps.googleusercontent.com")
//+ "&client_secret=" + HttpUtility.UrlEncode("dsflkdfsljkdfskjldskjlfds")
+ "&redirect_uri=" + HttpUtility.UrlEncode("http://localhost:50306/NextOAuthService/AdWordsOAuthService/AuthenticateAndGetRefreshToken")
+ "&scope=" + HttpUtility.UrlEncode("https://adwords.google.com/api/adwords")
+ "&access_type=offline";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
//handle webrequest stuff...
var request = (HttpWebRequest)WebRequest.Create(authUrl);// + postData);
if (request != null)
{
request.Method = "POST";
request.Timeout = 20000;
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length; // byteArray.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
//attempt to redirect to the Adwords OAuth URL: https://adwords.google.com/api/adwords&?response.....blah blah
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.RedirectKeepVerb;
WebOperationContext.Current.OutgoingResponse.Location = response.ResponseUri.AbsoluteUri;
return;
}
}
}
What's Actually Happening: When the code attempts the redirect, I get following exception:
The content type text/html; charset=UTF-8 of the response message does not match the content type of the binding (application/soap+xml;> charset=utf-8)
When I examine the response (using fiddler), the response contains the actual HTML code for the Google OAuth Sign In page. So, instead of redirecting the WCF to the url, I am instead receiving an html response containing the page source.
How do I get around this and force the redirect?
I think you are miss understanding the calls a bit. The First URL that you are building there is the one that you should be displaying to the user asking if they want to let you access there data.
You need to wait for them to except. You need to deal with the Authentication Code. Google 3 Legged OAuth2 Flow
You should consider using Googles dot net client lib. It will handle all this for you.

Categories

Resources