Configuring Windows user that an MVC application run under - asp.net-mvc

I am writing an MVC application which needs to request owner names for ip addresses from ARIN.net. Here is the snippet of program code that I have written to do this:
.
.
.
string requestUrl = "http://whois.arin.net/rest/ip/17.151.229.4";
WebResponse response = null;
WebRequest request = WebRequest.Create(requestUrl);
request.Proxy.Credentials = CredentialCache.DefaultCredentials;
response = request.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream());
XElement responseElmn = XElement.Parse(sr.ReadToEnd());
.
.
.
This snippet of code is successfully able to send a request to http://whois.arin.net/rest/ip/17.151.229.4 and receive the appropriate response when it is run from a console application on my machine. However, when I attempt to put this snippet of code in my MVC application, I get an exception stating
A connection attempt failed because the connected party did not
properly respond after a period of time, or established connection
failed because connected host has failed to respond .
My local machine, where these applications run, is inside the network of a very large corporation and therefore this snippet must send its request to ARIN through a proxy server when it is run by the previously mentioned applications. I believe that I'm probably receiving this discrepancy in results due to the console application running under a different user than the MVC application. I'm running both applications in debug mode in Visual Studio 2013. The MVC application is hosted by IIS Express when it is run in debug mode.
My questions are:
How can I find out what user the console application and the MVC application are run under?
How can I configure IIS Express to run the MVC application under a different user?
I have been unable to find answers to the questions in my research, any help is appreciated.

I discovered the cause of the problem. The MVC application didn't have a proxy server assigned to the proxy object member of the WebRequest instance by default, while the one in the console application did.
I therefore had to assign the proxy server to the proxy object instance of the WebRequest instance in my code before attempting to retrieve a response:
string requestUrl = "http://whois.arin.net/rest/ip/17.151.229.4";
WebResponse response = null;
WebRequest request = WebRequest.Create(requestUrl);
Uri newUri = new Uri("http://proxy.bigcorp.com:8080");
WebProxy myProxy = new WebProxy(newUri);
request.Proxy = myProxy;
request.Proxy.Credentials = CredentialCache.DefaultCredentials;
response = request.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream());
XElement responseElmn = XElement.Parse(sr.ReadToEnd());
Thank you Brendan Green for your help!

Related

TfsTeamProjectCollection does not ask for credential

Dears
Please help me with VS add-in Tfs connection question.
I've wrote VS 2017 plugin that uses TfsTeamProjectCollection class to connect to the tfs server. Tfs server is hosted in the https://dev.azure.com
However on certain computers it fails to connect to the Tfs server.
For example, I've tried to reproduce this and cleared all caches like described here. After clearing/connecting several cycles I've got the following:
VS Team Explorer is connected to the Tfs. I can checkout/checkin files, load history etc.
My add-in fails to connect with 401 non authorized error.
unity test started by VS is able to connect to the same Tfs using the same code
I've created sample console application that uses exactly the same class and method from add-in to connect and it works too.
Here is the source code I'm using to connect:
public override TfsTeamProjectCollection CreateCollection(WorkspaceInfo wi)
{
var s = (overrideConfig ?? Config);
var u = wi.ServerUri;
var vssCred = new VssClientCredentials(); // GetCredentials(s.Vsts);
Logger.Debug("getting collection for url:{0}", u);
TfsTeamProjectCollection tpc = null;
try
{
tpc = new TfsTeamProjectCollection(u, vssCred);
Logger.Debug("authenticating");
tpc.Authenticate(); // 401 non authorized exception here
}
I've tried to add vssCred.Storage = new VssClientCredentialStorage(); before Autheticate() but no luck
Then I've checked network packets using Fiddler application.
It shows the same request packet is sent using unit test, console application and add-in.
But console application and unit test produces initial request
POST
https://dev.azure.com/quipu-cwnet/Services/v3.0/LocationService.asmx
HTTP/1.1
and response is
HTTP/1.1 401 Unauthorized
X-TFS-FedAuthRedirect:
https://app.vssps.visualstudio.com/_signin?realm=dev.azure.com&reply_to=https%3A%2F%2Fdev.azure.com%2F...
Then console and unit test sends packet to the redirect url and asks for user credentials.
When add-in tries to connect to the Tfs server fiddler shows only first POST request and 401 response (with the same X-TFS-FedAuthRedirect header. But there is no redirection. From user side it looks like application freezes for some period after 401 response is obtained and then fails with 401 error.
Both Unit test and add-in assemblies has the same references to the 15.0.0 assemblies like Microsoft.TeamFoundation.VersionControl.Client and related.
I've tried VssConnection but the same
VssConnection connection = new VssConnection(u, vssCred);
connection.ConnectAsync().SyncResult();
var prj = connection.GetClient<ProjectHttpClient>();
var prjCollection = prj.GetProjects().Result; // 401 error here when is executed as VS add-in
foreach (var pc in prjCollection)
Logger.Debug("\tVssConnection project {0} {1}", pc.Id, pc.Name);
I'm using the same user to start VS (and add-in) and console. No elevated permissions.
Is there anything I can do with TfsConnection when used as VS add-in ?
the answer is to execute Authenticate() in the separate thread (non GUI) :crazy
var authTask = Task.Run(() => tpc.Authenticate());
authTask.Wait();
Please note that I'm using VS 2017 15.9.11 and Microsoft.TeamFoundationServer.ExtendedClient.15.112.1
upd1: I've upgraded Microsoft.TeamFoundationServer.ExtendedClient to 15.113.1
it works on my machine but still fails on my colleague machine.
Tfs credentials are working like a charm on both machines:
var tfsClientCredentials = TfsClientCredentials.LoadCachedCredentials(wi.ServerUri, false, false);
var res = new TfsTeamProjectCollection(wi.ServerUri, tfsClientCredentials);
res.EnsureAuthenticated();
despite the fact it is marked as obsolete.

Simple POST from website to external web api fails

I have an asp .net MVC-page
Im trying to connect to Eventbrite:s api
Simply put, it requires you to send client id to one url, using HttpGET and HttpPOST the result and some more info to another url.
The GET goes fine and I get the required (auth)"code". When I try to make the POST to the second url I get
"Socket Exception: An existing connection was forcibly closed by the
remote host"
I can POST to the second url, using Postman and the info from the GET-request it works ok, I get the auth token just fine.
This is the code Im using
var parameters = new Dictionary<string,string>();
parameters.Add("code", pCode);
parameters.Add("client_secret", CLIENT_SECRET);
parameters.Add("client_id", CLIENT_APP_KEY);
parameters.Add("grant_type", "authorization_code");
using (var client = new HttpClient())
{
var req = new HttpRequestMessage(HttpMethod.Post, pUrl) { Content = new FormUrlEncodedContent(parameters) };
var response = client.SendAsync(req).Result;
return response.Content.ReadAsStringAsync().Result;
}
I have a vague memory of a similar problem when publishing to Azure. Since I have to register my app with a public return url I cant look at the request with fiddler.
My site is running https.
I have also tested adding the below line (from some googling)
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
But then I get 404-error...
I have also tested this (with same result)
using (var client = new HttpClient())
{
var response = client.PostAsync(pUrl, content).Result;
authToken = response.Content.ReadAsStringAsync().Result;
}
Ive tested getting the auth code and and running the POST from local machine, same result...
I have contacted eventbrite developer support to see if they can help me as well...
This POST must contain the following urlencoded data, along with a Content-type: application/x-www-form-urlencoded header.
Since your content-type is application/x-www-form-urlencoded you'll need to encode the POST body, especially if it contains characters like & which have special meaning in a form.
Then use the following function to post your data:
using (var httpClient = new HttpClient())
{
using (var content = new FormUrlEncodedContent(parameters))
{
content.Headers.Clear();
content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
HttpResponseMessage response = await httpClient.PostAsync(url, content);
return await response.Content.ReadAsAsync<TResult>();
}
}
The error message you provided means the remote side closed the connection, the causes are:
·You are sending malformed data to the application.
·The network link between the client and server is going down for some reason.
·You have triggered a bug in the third-party application that caused it to crash.
·The third-party application has exhausted system resources.
·Set ServicePointManager.SecurityProtocol = ServicePointManager.SecurityProtocol | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
For more details, you could refer to this case.
Changed OAuth access token URL from
https://www.eventbrite.com/oauth/token/
to (as specified)
https://www.eventbrite.com/oauth/token
(ie without trailing slash). Now it works

Get "the underlying connection was closed an unexpected error occurred on a send" error when calling CompleteSale method

I'm having a problem calling the API's method CompleteSale via eBay_Service .NET SDK (v967) since 2 weeks (02/10).
When the ERP tries to sends some updated information about one order, it receives this Exception:
the underlying connection was closed an unexpected error occurred on a send
so I haven't got a response from the API.
There are more than one strange things:
there are some batch in background, using the same .dll, and they
work fine;
after rebooting the server the first call to "CompleteSale" works fine;
after registering again the .dll via the "regsrv" command, it worked
fine for one day;
all operators that uses the ERP are connected to the server via
remote desktop and all of they notice the problem. Instead, if i
connect from my company's office, all works fine;
I've tried to increase the timeout to 360 sec (from 60 sec) and nothing changed.
The ERP is developed in progress (OpenGL) , so I can't fix with setting "KeepAlive" to "false", setting the certificate explicitly (Tsl1.1 | Tsl1.2) or making other interventions on .net side. I was wrong, it can be done from the source code of the SDK.
i've checked the Security Protocols on the api's servers discovering that the "SSL3" is not longer supported whereas the default value for the ServicePointManager.SecurityProtocol in .NET 2.0 is SSL3.
I've solved the problem by adding this hotfix at the "eBayXmlAPIInterfaceService" class in the SDK's source code:
//768 = Tsl1.1, 3070 = Tsl1.2
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072 |
(SecurityProtocolType)768;
HttpWebRequest http = (HttpWebRequest) WebRequest.Create(this.Url);
http.Method = "POST";
http.ContentType = "text/xml";
http.ContentLength = data.Length;
http.KeepAlive = false;
Probably Microsoft as released an hotfix to correct this problem but the server wesn't updated since 2015.
Moreover i've replicated the .net code in the ABL application in a program that we use to do get/post requestes:
DEF VAR w-tsl10 AS System.Net.SecurityProtocolType
w-tsl10 = CAST(System.Enum:ToObject(PROGRESS.Util.TypeHelper:GetType("System.Net.SecurityProtocolType":U), 192), System.Net.SecurityProtocolType).
ystem.Net.ServicePointManager:SecurityProtocol = w-tsl10.
link to the security protocol verifier: https://www.ssllabs.com/ssltest/index.html
I was working with betfair api and got this issue. After some research I found this
System.Net.ServicePointManager.Expect100Continue = true;
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

Proxy for OAuthUtil.GetAccessToken

I've setup a perfectly functioning application (in VB) that allows user to access his Google Sheets.
The application follows Google's OAuth documentation for displaying a sign-in dialog in a web browser, obtains user's permission and access codes, uses access codes to obtain access token, and then uses the Google Sheet's Query service to get hold of Google Sheets. Very simple. Works fine.
Problem occurs on computers that have internet proxy defined on them. In the rest of my application and most of Google Sheets API, I can define a manual internet proxy. GData's RequestFactory allows manually configuring proxy server. The only line of code that doesn't support (to my current knowledge) is the OAuthUtil library used for obtaining access token. It doesn't allow defining internet proxy server, hence it is unable to resolve host on computers behind proxy environment. Following is my pseudo code:
Dim parameters As New OAuth2Parameters
parameters.ClientId = CLIENT_ID
parameters.ClientSecret = CLIENT_SECRET
parameters.RedirectUri = REDIRECT_URI
parameters.Scope = SCOPE
>>Show browser window and obtain access code
parameters.AccessCode = login.Token
OAuthUtil.GetAccessToken(parameters) '<< Point of failure
Dim requestFactory As GOAuth2RequestFactory = New GOAuth2RequestFactory(Nothing, My.Application.Info.ProductName, parameters)
requestFactory.Proxy = GetProxySettings() '<< my code for defining proxy
myService = New SpreadsheetsService("Application")
myService.RequestFactory = requestFactory
Another important aspect is that my application works on Mac OSX as well using Wine (for web browser I use GeckoFX). If internet proxy is globally defined on the environment then the OAuthUtil works fine, but this doesn't work for Wine. I have tried setting internet proxy in the command-line environment, or in the registry and refreshed system settings, still the applications running in Wine do not understand that proxy is defined. Hence proxy has to be manually defined.
I need help to figure out a solution by any of the following:
* A way to forcefully/manually define proxy for OAuthUtil for obtaining access token
* Any other way to obtain OAuth access token if proxy cannot be defined as above (maybe WebClient can be used?)
* Some way to define global internet proxy in Wine so applications like GData API read and understand the proxy setting. Though I'd rather prefer manually defined proxy at application level.
Any ideas folks?
Regards
F.A.
I've figured it out. Turns out that the 'OAuthUtil.GetAccessToken' only uses system-defined proxy. There is no way to manually define internet proxy, like RequestFactory supports. So there is a work-around using WebClient:
Try
'// Get access token from code
Using WC As New WebClient
' Define proxy
WC.Proxy = GetProxySettings()
' Set parameters
WC.Headers(HttpRequestHeader.ContentType) = "application/x-www-form-urlencoded"
' Get response
Dim postURL = "https://www.googleapis.com/oauth2/v4/token"
Dim postParams = "code=" & parameters.AccessCode &
"&client_id=" & Uri.EscapeDataString(CLIENT_ID) &
"&client_secret=" & Uri.EscapeDataString(CLIENT_SECRET) &
"&redirect_uri=" & Uri.EscapeDataString(REDIRECT_URI) &
"&grant_type=authorization_code"
Dim responsebody As String = WC.UploadString(postURL, postParams)
' Read response
Dim jObj As JObject = JsonConvert.DeserializeObject(responsebody)
' Store token
parameters.AccessToken = jObj("access_token").ToString
parameters.RefreshToken = jObj("refresh_token").ToString
parameters.TokenType = jObj("token_type").ToString
parameters.TokenExpiry = Now().AddSeconds(CDbl(jObj("expires_in").ToString))
End Using
Catch ex As Exception
MsgBox("Error obtaining access token: " & ex.Message, MsgBoxStyle.Critical)
Return Nothing
End Try

How to send text from Windows Phone 8.1 via HttpWebRequest / POST?

I have a web service that expects (unicode UTF-8 encoded) text data as an HTTP POST message.
I'd like to use it from a Windows Phone 8.1 runtime client.
I created the client, but it does not invoke the web URI.
Here's the code I use on the client:
Can anyone tell what am I missing?
Thanks,
B
{
...
SendText("http://192.168.1.107:58709/UploadText.aspx"); // The IP belongs to the web server, port is correct. I can invoke it from a browser.
...
}
string StringToSend = "This is a test string uploaded via HTTP POST from WP8";
private void SendText(string Url)
{
System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)WebRequest.Create(Url);
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
request.BeginGetRequestStream(new AsyncCallback(UploadText_GetRequestStreamCallback), request);
}
public void UploadText_GetRequestStreamCallback(IAsyncResult asyncResult)
{
System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)asyncResult.AsyncState;
Stream postStream = request.EndGetRequestStream(asyncResult);
byte[] postDataAsBytes = System.Text.Encoding.UTF8.GetBytes(StringToSend);
postStream.Write(postDataAsBytes, 0, postDataAsBytes.Length);
postStream.Flush();
// postStream.Close(); // Close is not available in Windows Phone 8.1 runtime project.
// request.ContentLength = postDataAsBytes.ToString(); // request.ContentLength is not available in Windows Phone 8.1 runtime project.
request.Headers["Content-length"] = postDataAsBytes.ToString();
request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
}
OK, it seems the code was correct...
Problem was, that the phone emulator could not connect to the development server (IIS Express). I searched the web over, tried a number of solutions, but I could not make it happen. In the meantime I trashed my wifi connection, had to remove and reinstall Hyper-V to make it work again.
The workaround was to publish the test web app to the local IIS (make sure it is the Debug version that is published) then attach to it from the debugger, call from WP8.1 emulator - and it works.

Resources