In a ASP.Net Core website I am using NLog with a StackifyTarget to log to Stackify Retrace. Our code is running behind a corporate HTTP proxy.
I have some custom code that returns a WebProxy.
The WebProxy is then set on StackifyLib.Utils.HttpClient.CustomWebProxy, in the Configure method of the StartUp.cs.
When a log is written, it is written successfully to file, but not to the StackifyTarget.
When I investigate the network traffic using Fiddler, I can see that there are 407/Proxy AuthenticationRequired errors for outbound traffic to the Stackify servers.
Using the same StackifyTarget in a WinForms application, .Net Framework 4.7.2, it just works fine:
<system.net>
<defaultProxy useDefaultCredentials="true" />
</system.net>
When I set a breakpoint on the Log.Info, I can see that the proxy information is still set on the StackifyLib.
How can have StackifyLib work correctly with the proxy, in ASP.Net Core?
The custom code that assigns proxy to CustomWebProxy could also try and assign this first:
System.Net.WebRequest.DefaultWebProxy = webProxy;
As the very first thing in the application, before Stackify-HttpClient is created.
Stackify has 2 docs that may help with this:
https://docs.stackify.com/docs/troubleshoot-errors-and-logs-net-configurations
https://docs.stackify.com/docs/http-proxies-configure
If either of these do not work you can submit a ticket to them to support#stackify.com
Related
I'm trying to debug a call to my ServiceStack web service from a .net 472 application. Fiddler has always been the obvious choice for inspecting traffic in my other applications targeting the same service.
Strangely, I cannot get Fiddler to capture any traffic when using the GetAsync() method of the JsonServiceClient. The call returns data as expected without issue, just not tracked in Fiddler:
var response = await client.GetAsync(new AroCodesRequest());
However, if I use the Get() method, Fiddler captures the traffic as expected:
var response = client.Get(new AroCodesRequest());
(Edit) Adding the following to App.config doesn't help:
<system.net>
<defaultProxy>
<proxy proxyaddress="http://127.0.0.1:8888" bypassonlocal="False" />
</defaultProxy>
</system.net>
I've put Fiddler into troubleshooting mode, still no luck. I've been unable to find much helpful information on Google/SO, I suspect I may simply not be asking the correct question.
Update
Downgrading from ServiceStack 5.6.0 to 5.5.0 has caused Fiddler to capture the traffic again. I'm guessing it has something to do with this line in the 5.6.0 release notes - https://docs.servicestack.net/releases/v5.6#service-clients-async-webproxy - I don't fully understand whats going on, I'll keep looking at it.
In v5.6 the AsyncServiceClient uses the Proxy configured on the ServiceClient, previously it didn't. But it used the Proxy even if one wasn't configured which looks like causes this issue where setting it to null seems to unset the Proxy configuration in your Web.config.
I've changed it to only use the proxy if one was configured in this commit.
This change is available from v5.6.1 that's now available on MyGet.
I have a console app built on .NET 4 that uses the HttpClient library (obtained via NuGet) to retrieve data from a public API over the internet. The console app sits behind a proxy. The Windows machine it sits on has the correct proxy settings in Internet Explorer. When the console application attempts to access the outside world it is given a 407 status - "proxy authentication required".
I've written no specific code to deal with a proxy yet. I'm assuming from the 407 error that the application is directing to the proxy no problem, but the proxy isn't authenticating the request.
My question is, is it possible to set the HttpClient to use the credentials of the logged in user to authenticate the proxy? If so, how?
var client = new HttpClient(webRequestHandler);
client.PostAsync(RequestUri, MyContent);
I managed to solve my problem very simply through proxy configuration in app.config.
<system.net>
<defaultProxy enabled="true" useDefaultCredentials="true">
<proxy usesystemdefault="True" />
</defaultProxy>
</system.net>
http://msdn.microsoft.com/en-us/library/dkwyc043.aspx
If you wanted to do the same programmatically you could use the following:
WebRequest.DefaultWebProxy.Credentials = CredentialCache.DefaultNetworkCredentials;
(These objects are from the `System.Net' namespace).
Some more info from MSDN: http://msdn.microsoft.com/en-us/library/system.net.webproxy.getdefaultproxy.aspx
I have a new Web API developed in ASP.NET Core. This Web API is supposed to be deployed in IIS and will have to work over SSL, so I have the [HttpsRequired] attribute on all my controllers. I struggle to make it work while deployed, so for now I relaxed the requirements and commented out those attributes. Doing so, I was able to create two bindings in IIS, one for HTTPS and one for HTTP. Given that my Web API is created in ASP.NET Core, I followed the deployment steps Rick Strahl has in his excellent blog post. I have selected "No Managed Code" for the .NET CLR version. The IIS machine is a 64-bit Windows Server 2012 R2 environment - not sure whether this matters or not. The .NET Core Windows Server Hosting bundle has been installed on the server and I can see the AspNetCoreModule listed in the Modules grid.
If i try to access the Web Api (I created a very simple GET method that returns some information regarding the assembly) with Fiddler, I get a 404 error. For now, i run Fiddler on the same machine, so I tried all combinations (localhost, IP address and full machine name in the domain).
No errors are logged in the EventViewer. Does anyone have any suggestion on how to troubleshoot this issue?
TIA,
Eddie
EDIT1: Here is my controller:
[Route("api/info")]
//[RequireHttps]
public class InfoController : Controller
{
private ITncRepository _repository;
public static ApplicationAssemblyDetails ApplicationAssemblyDetails { get; set; }
public InfoController(ITncRepository repository)
{
_repository = repository;
ApplicationAssemblyDetails = ApplicationAssemblyDetails.Current;
}
[HttpGet("")]
public JsonResult Get()
{
return Json(new WebApiInfoModel()
{
CurrentTime = DateTime.Now,
CurrentUtcTime = DateTime.UtcNow,
AssemblyName = ApplicationAssemblyDetails.ApplicationAssembly.FullName,
VersionNumber = ApplicationAssemblyDetails.VersionNumber,
BinFolder = ApplicationAssemblyDetails.BinFolder,
BuildMode = ApplicationAssemblyDetails.BuildMode,
TradeMark = #" © 2016-2017 * SomeCompany (www.somecompany.com)"
});
}
}
The ApplicationAssemblyDetails is a nuget package that gives some info about the current assembly. WebApiInfoModel is my model class for the Web API Information I want to pass back as a test to the client.
The web.config file:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath=".\My_ASP_NET_Core_Web_API.exe" arguments="" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="true" />
</system.webServer>
</configuration>
Finally, to answer your last question, Ignas, I use a Publishing Profile that uses the File system as a method, targets the .NET Framework 4.5.2, using the release configuration. Given that my project is a Web API and not an MVC 6 Web Application, the publishing package creates a stand-alone application. Since the clients need to call my Web API using SSL, I think that it has to be hosted in IIS, so running the standalone application would not work. Of course, for testing purposes, I could try to run it. That's why I commented out the [HttpsRequired] attribute. I will try that and report back, but for now I hope I gave you all the information you required.
I'm having a setup very close to yours (Asp.Net core, Web API, IIS, HTTPS ...) working fine on my end.
I faced the same issue at some point because I was not using the proper path to access my controller/action, it depends on how you deployed it under IIS. For instance, in my case when I use Kestrel directly it goes through a URL like that:
http:// localhost:5000/controllerName/actionName
But I can also contact my Web API via IIS and in that case I need to use a URL like that:
http:// localhost:5001/applicationName/controllerName/actionName
Have you created an application under IIS that could explain you getting a 404 because you would not use the proper path?
For instance, in my case:
screenshot of the asp.net core api under iis
And I'm accessing it, through the URL:
https: //servername:serverport/RequestPortalAPI/ControllerName/ActionName
In the end, it was a matter of properly configuring Widows Authentication. For Fredrik and anyone else reading this post for a solution, these are the steps I performed:
In IIS, in the Authentication form for my Web API, I disabled Anonymous Authentication and I enabled Windows Authentication:
Make sure that "Negotiate" is at the top of the list for Enabled Providers:
In the Application Pools, I configured my Web API to run under an account that the UIT department of my client has given me:
The configuration file of my Web API (web.config) contains the following settings:
Now we are getting into the dark areas of the problem. In order to use Windows Authentication and let the credentials of the caller be passed through to the backend (in my case a SQL Server database), the Web API has to be configured to use Kerberos. I found this after I opened a ticket with Microsoft and I worked closely with one of their engineers. For this to happen, you need to follow these steps:
Create a Service Principal Name (SPN) for your Web API and the domain account it runs under. You need to run this command:
Where hostname is the fully qualified domain name of your Web API. The Domain\Username are the domain account under which the Web API is running. You need special domain privileges, so you may want to involve someone from IT. Also, from now on, you need to access your Web API by the full domain name, not by IP address. IP address won't work with Kerberos.
Also, with the help of your IT person, you need to enable delegation for any service using Kerberos for the domain account under which you run your Web API. In the Active Directory Users and Computers, locate the account you use to run your Web API, bring up its properties, click on the Delegation tab and enable the second option "Trust this user for delegation to any service (Kerberos Only):
We have also made some changes on the server that runs our database, but I am not 100% those are truly required, so I won't add them here because I don't even know if you use SQL Server or some other backend repository.
Let me know if you need those as well and I will add them later.
Good luck,
Eddie
I have a asmx web service running on a test server that has anonymous access enabled.
When I add the web reference to a console application and call a simple Hello World method like so:
PivotService.PivotService p = new PivotService.PivotService();
String s = p.SayHello();
When I do exactly the same thing in the page load of a web application I get a System.Net.WebException: {"Unable to connect to the remote server"}.
The inner exception is {"No connection could be made because the target machine actively refused it 127.0.0.1:8888"}, errorCode 10061.
Why would this work from a console app and not a web app?
It could be due to differences in the proxy settings between applications. Check out the MSDN documentation around the Default Proxy element in config file.
I too was in a similar situation while using HttpClient class from System.Net.Http namespace. I was trying to make a network call which goes through the company proxy server.
While this HttpClient call was able to successfully resolve the IP of the dns when called from a console app in visual studio the dns resolution failed when the call was made from a Web API. And it turned out that I had to have this entry in the web.config of the web api app.
<system.net>
<defaultProxy />
</system.net>
Credit to Mark 909's answer for pointing me in right direction. Please see Default Proxy for additional information.
c#httpclientwebapi
First remove web reference from console
run you web service and copy the URL
go to your solution explorer and add web reference(Exclude old one)>Advanced>Add web Reference
add paste URL then add your web reference name then rebuild your solution
it works fine for me
As #R Kiran Kumar suggests, I had to also add the proxy values:
<system.net>
<defaultProxy>
<proxy usesystemdefault="False"
proxyaddress="Specify Your Proxy Address: Specify Port Number"
// Example, "http://192.168.0.10:1234"
bypassonlocal="False"/>
</defaultProxy>
</system.net>
Use this line :
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
Just above the httpclient object creation
I am tring to debug whats wrong with my HTTP requests from another question here on SO. So i read a bit about Fiddler and wanted to use it to debug my problem. But I can't seem to get traffic from my WPF application to go through Fiddler. I believe I need to configure a proxy. I am using a WebClient for a basic example, but I think i will require a WebRequest later. But for now, with a simple WebClient, how can I get it to go through Fiddler (I believe I have to set proxy to localhost:8888)?
UPDATE:
I don't know if i did the right thing or not but I tried
var wc = new WebClient();
WebProxy proxy = new WebProxy();
proxy.Address = new Uri("http://localhost:8888");
wc.Proxy = proxy;
but failed - I don't see any traffic in Fiddler
I tried ...
var wc = new WebClient();
WebProxy proxy = new WebProxy("127.0.0.1", 8888);
wc.Proxy = proxy;
still nothing
I found the solution at this fiddler2.com page
Why don't I see traffic sent to
http://localhost or http://127.0.0.1?
Internet Explorer and the .NET Framework are hardcoded not to send
requests for Localhost through any
proxies, and as a proxy, Fiddler will
not receive such traffic.
The simplest workaround is to use your machine name as the hostname
instead of Localhost or 127.0.0.1. So,
for instance, rather than hitting
http://localhost:8081/mytestpage.aspx,
instead visit
http://machinename:8081/mytestpage.aspx.
Maybe a little late, but...
I get around this simply by appending a "dot" to localhost, so instead of accessing localhost, I try to access localhost. (notice the dot at the end of the hostname)
Credit where credit is due:
I got this unusual tip from this thread http://www.west-wind.com/weblog/posts/2009/Jan/14/Monitoring-HTTP-Output-with-Fiddler-in-NET-HTTP-Clients-and-WCF-Proxies#596591
Works fine!
You can find answer in below post
https://stackoverflow.com/a/7506427/471499
it lists that you need to add this in your web.config OR App.Config
<system.net>
<defaultProxy>
<proxy bypassonlocal="False" usesystemdefault="True" proxyaddress="http://127.0.0.1:8888" />
</defaultProxy>
</system.net>
then Start Fiddler on the same machine as the application running.
Click Tools | Fiddler Options => Connections => adjust the port as 8888.(allow remote if you need that)
Ok, then from file menu, capture the traffic.
That's all, but don't forget to remove the web.config lines after closing the fiddler, because if you don't it will make an error.
Run Fiddler for DotNet Core requests
RUN FIDDLER for .net core required "Netsh" tool https://learn.microsoft.com/en-us/windows-server/networking/technologies/netsh/netsh-contexts)
command to add proxy :
netsh winhttp set proxy 127.0.0.1:8880
After run the proxy, adjust Fiddler proxy to the same port, and enjoy
remove proxy
netsh winhttp reset proxy
Reference :
http://fiddler2.com/documentation/Configure-Fiddler/Tasks/UseFiddlerAsReverseProxy
https://docs.telerik.com/fiddler/configure-fiddler/tasks/configuredotnetapp
All the time I use below configuration to redirect the network HTTP calls to pass thru fiddler proxy from my applications.
This works in all kinds of .NET applications (which has either web.config or app.config file) and in fiddler its best to disable Capture Traffic option to avoid capturing general traffic from all the applications running. Shortcut key for this is F12.
<system.net>
<defaultProxy>
<proxy proxyaddress="http://localhost:8888/" />
</defaultProxy>
</system.net>
This is valuable configuration if you have third party assemblies in which you don't have chance of changing the code that calls URL.
I hope this helps someone.
"IIS Express won't receive traffic to machinename so instead route to localhost.fiddler fiddler2.com/documentation/Configure-Fiddler/Troubleshooting/… – robrich May 9 '13 at 6:02"
RobRich above got it right.
This is the only thing that worked as I can only use IIS Express.