WebAPI and https not playing well together - https

I'm getting errors (strange ones) when I try to do GET,PUT,POST,DELETE with https to the same WebAPI controller calls that work http. Is there any special web.config magic that is needed for https with WebAPI controllers?
** ADDING ERROR:
(this is the error code I get when I hit the same GET web api controller as the one that works with http. that is, http works, https fails with this error)
{"message":"An error has occurred.","exceptionMessage":"A null value was returned where an instance of HttpResponseMessage was expected.","exceptionType":"System.InvalidOperationException","stackTrace":" at System.Web.Http.Controllers.ResponseMessageResultConverter.Convert(HttpControllerContext controllerContext, Object actionResult)\r\n at System.Web.Http.Controllers.ApiControllerActionInvoker.<>c__DisplayClass3.<InvokeActionAsync>b__1(Object value)\r\n at System.Threading.Tasks.TaskHelpersExtensions.<>c__DisplayClass3b`2.<Then>b__3a(Task`1 t)\r\n at System.Threading.Tasks.TaskHelpersExtensions.ThenImpl[TTask,TOuterResult](TTask task, Func`2 continuation, CancellationToken cancellationToken, Boolean runSynchronously)"}

Related

ASP.NET Core 3.0 React app errors: failed to proxy

(FYI, this is my first Microsoft project of any type and I am not familiar with technologies like proxy servers, etc so my description of the issues may not be the greatest).
I have been working on an ASP.NET Core 3.0 (preview) React app for the past month or so without any issues. Last Friday I started updating the web api to pull data from the database for charting in the UI. This week I picked up where I left off but my project now errors on start up.
Events that occurred since it was last working... I installed and used Fiddler briefly on Friday to run some api calls but then switched over to Postman. Everything was fine and I left everything running (may have closed Fiddler, don't recall). This week I made some database changes (set a multi-column index via the Fluent API) and added more data to the database (SQL Server). I then proceeded to continue working on the web api starting with a request in Postman but it errored. I went to view the app UI but that errored as well.
After two days of googling/troubleshooting I think the most useful error given is the one below. From the error messages, I do not know where port 50158 is coming from. The app loads at https://localhost:44398/. I performed a search for "50158" on my whole computer and only found it in IIS log files. Here are the first 4 lines in each log file. The rest of each file mentions only '44398'.
Successfully registered URL "https://localhost:44398/" for site "MyAwesomeApplication" application "/"
Successfully registered URL "http://localhost:50158/" for site "MyAwesomeApplication" application "/"
Registration completed for site "MyAwesomeApplication"
Request started: "GET" https://localhost:44398/
I found some posts on SO that mention Fiddler causing similar issues to this error, however, they have not helped me resolve the problem.
Some posts on SO mention unchecking "Automatically detect settings" on the Internet Properties > Connections > LAN settings. It is indeed unchecked on my computer.
Some things I have tried:
I created a new project using all the same specifications but get the same errors.
I completely removed Fiddler.
I reverted the latest database changes.
Where is this problem coming from and what do I need to do to fix it?
Please let me know if more (and what) info would be useful. This issue is out of my current knowledgebase.
#
Error message (sorry, not sure how to format it nicely)
An unhandled exception occurred while processing the request.
SocketException: No connection could be made because the target machine actively refused it.
System.Net.Http.ConnectHelper.ConnectAsync(string host, int port, CancellationToken cancellationToken)
HttpRequestException: No connection could be made because the target machine actively refused it.
System.Net.Http.ConnectHelper.ConnectAsync(string host, int port, CancellationToken cancellationToken)
HttpRequestException: Failed to proxy the request to http://localhost:50158/, because the request to the proxy target failed. Check that the proxy target server is running and accepting requests to http://localhost:50158/.
The underlying exception message was 'No connection could be made because the target machine actively refused it.'.Check the InnerException for more details.
Microsoft.AspNetCore.SpaServices.Extensions.Proxy.SpaProxy.PerformProxyRequest(HttpContext context, HttpClient httpClient, Task baseUriTask, CancellationToken applicationStoppingToken, bool proxy404s)
Stack Query Cookies Headers Routing
SocketException: No connection could be made because the target machine actively refused it.
System.Net.Http.ConnectHelper.ConnectAsync(string host, int port, CancellationToken cancellationToken)
Show raw exception details
HttpRequestException: No connection could be made because the target machine actively refused it.
System.Net.Http.ConnectHelper.ConnectAsync(string host, int port, CancellationToken cancellationToken)
System.Threading.Tasks.ValueTask.get_Result()
System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, bool allowHttp2, CancellationToken cancellationToken)
System.Threading.Tasks.ValueTask.get_Result()
System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
System.Threading.Tasks.ValueTask.get_Result()
System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
System.Threading.Tasks.ValueTask.get_Result()
System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, bool doRequestAuth, CancellationToken cancellationToken)
System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task sendTask, HttpRequestMessage request, CancellationTokenSource cts, bool disposeCts)
Microsoft.AspNetCore.SpaServices.Extensions.Proxy.SpaProxy.PerformProxyRequest(HttpContext context, HttpClient httpClient, Task baseUriTask, CancellationToken applicationStoppingToken, bool proxy404s)
Show raw exception details
HttpRequestException: Failed to proxy the request to http://localhost:50158/, because the request to the proxy target failed. Check that the proxy target server is running and accepting requests to http://localhost:50158/. The underlying exception message was 'No connection could be made because the target machine actively refused it.'.Check the InnerException for more details.
Microsoft.AspNetCore.SpaServices.Extensions.Proxy.SpaProxy.PerformProxyRequest(HttpContext context, HttpClient httpClient, Task baseUriTask, CancellationToken applicationStoppingToken, bool proxy404s)
Microsoft.AspNetCore.Builder.SpaProxyingExtensions+<>c__DisplayClass2_0+<b__0>d.MoveNext()
Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
IdentityServer4.Hosting.IdentityServerMiddleware.Invoke(HttpContext context, IEndpointRouter router, IUserSession session, IEventService events)
IdentityServer4.Hosting.MutualTlsTokenEndpointMiddleware.Invoke(HttpContext context, IAuthenticationSchemeProvider schemes)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
IdentityServer4.Hosting.BaseUrlMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.MigrationsEndPointMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Show raw exception details
For me it had to do with cookie size being too large for development server.
I was working on a React client app served by ASP.NET Core 3.1 with Keycloak as an OP.
Fresh React templates did also suddenly not start anymore.
Clearing cookies made my projects start again.
ref:
https://techcommunity.microsoft.com/t5/iis-support-blog/400-error-in-asp-net-core-project-because-of-8-kb-cookie-limit/bc-p/1308877#M431
I decided to try and roll all the NuGet packages to a previous version (v3.0.0-preview5-19227). My app now functions as expected. Looking at the download page for dotnet-core, it looks like v3.0.0-preview6 was released on 06/12. I started my project way before that so maybe I updated the packages and just don't recall??? Either way, time to make up for 2 days lost.

Passing Multiple Get Parameters to WebApi

I am working on a asp.net core 2.2 application. I want to pass two parameters(token and refresh token) to the asp.net core 2.2 web api to retrieve new token. When I am passing the values, i am getting an error
An unhandled exception occurred while processing the request.
AggregateException: One or more errors occurred. (Response status code does not indicate success: 404 (Not Found).)
System.Threading.Tasks.Task.Wait(int millisecondsTimeout, CancellationToken cancellationToken)
HttpRequestException: Response status code does not indicate success: 404 (Not Found).
Is this right way to pass multiple parameters and route it?
requestUrl is build as below:
string requestUrl = string.Format(Token_RefreshUserToken + "/{0}"+"/{1}", token,refreshToken);
requestUrl value is(web api controller name is 'Token'):
"Token/Refresh/eyJhbGciOiJIQrI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InJlZnJhbmNpc0BzdXlhdpdGkuY54tIiwiZXhwIojxNTYwMzMyOTk7hCJpc3MiOiJodHRwOi8vd3d3LnNlY3WeaXR5Lm9yZyIsImF1ZCI3rdh0dHA6Ly93d3cuc2VjdXJpdHkub3JnIn0.2Iw0VS_OgMjfpgt5V27mjCuLLqzlZBgRMpYgCTEHRP88E/IDwRYkf9idsVrBhBJJ5ymS+8RrZuSBSl+wywuKCs+Bw="
Client:
Task<TokenModel> userToken = _commonHelper.RecreateUserToken(tokenModel.TokenVal, tokenModel.RefreshToken);
userToken.Wait();
public async Task<TokenModel> RecreateUserToken(string token, string refreshToken)
{
string url = string.Format(WebApiConstants.Token_RefreshUserToken + "/{0}"+"/{1}", token,refreshToken);
var statusResponse = await _ApiHelper.GetAsync(url);
tokenData = await statusResponse.Content.ReadAsAsync<TokenModel>();
return tokenData;
}
Web Api method :
[HttpGet]
[Route("Refresh/{token}/{refreshToken}")]
public async Task<TokenValue> Refresh(string token, string refreshToken){ //logic }
It seems that request containing double escape sequence caused the problem.In development mode, try to run the web api project with Kestrel instead of IIS express.
ASP.NET Core application could be hosted on variety of web servers (IIS, Kestrel, Nginx, Apache, ...). All these web servers know nothing about request filtering (and particularly enabling of double escape) which is a native IIS feature. It's a hosting concern and ASP.NET Core application should not deal with it directly. If URL like http://youserver.com/Home/Phone/+12345 will reach ASP.NET Core pipeline, plus sign will not be treated in any special way and will get to string model as + character.
When you host your application on IIS, web.config is still in use, so you could configure <requestFiltering allowDoubleEscaping="true"/> as for usual ASP.NET application.
<system.webServer>
<security>
<requestFiltering allowDoubleEscaping="true" />
</security>
If you want to host application in another Web server, you should check how it handle special characters. Kestrel will just pass such URLs as is, so you don't need to take any specific actions if hosted on Kestrel.
Refer to here

A bad request call to my asmx service causes a http 500 error, what can I do to make it return a http-400 error instead?

I have an ASMX service hosted in IIS 7.5. When it is called with a bad http request (having an empty string value for "host" in the http header), the service returns a http-500 (internal server error). To satisfy company security requirements, it should return a http-400 (bad request) under this situation.
I have verified that the error occurs at the service infrastructure level, and the exception is not thrown from my code. I put try/catch block around the web method but nothing is caught, and the application log has nothing. So the error occurs before my code is executed.
I know WCF can handle the problem gracefully with IErrorHandler; but that's not an option for me at the moment.
Another interesting fact is that when testing inside Visual Studio, the same request causes a 400-error, my desired result.
So my question is: what can I do to make the service hosted under IIS also return a 400 error to a bad request?

How do I configure MaxReceivedMessageSize in IIS hosted ASP.NET Web API (v1)?

EDIT: I mis-diagnosed the exception. It was from a WCF client call in my Web API controller, not from the Web API client. Easy to fix by setting the maxReceivedMessageSize in my WCF client binding config.
I am exceeding the maximum message size in Web API. I can find how to configure it in WCF and in self-hosted Web API, but I can't find where to configure it in IIS hosted Web API.
Here is the exception:
CommunicationException The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize prop
erty on the appropriate binding element. Void HandleReturnMessage(System.Runtime.Remoting.Messaging.IMessage, System.Runtime.Remoting.Messaging.IMessage)
Server stack trace:
at System.ServiceModel.Channels.HttpInput.ThrowMaxReceivedMessageSizeExceeded()
at System.ServiceModel.Channels.HttpInput.ReadBufferedMessage(Stream inputStream)
at System.ServiceModel.Channels.HttpInput.ParseIncomingMessage(HttpRequestMessage httpRequestMessage, Exception& requestException)
at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ClientReliableChannelBinder`1.RequestClientReliableChannelBinder`1.OnRequest(TRequestChannel channel, Message message, TimeSpan timeout, MaskingMode maskingMode)
at System.ServiceModel.Channels.ClientReliableChannelBinder`1.Request(Message message, TimeSpan timeout, MaskingMode maskingMode)
at System.ServiceModel.Security.SecuritySessionClientSettings`1.SecurityRequestSessionChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Where can I access the the Web API binding settings so I can set the MaxReceivedMessageSize?
Your post is confusing...your exception is related to WCF self host but your question is about IIS hosted application...they both are different...anyways here are the options for both hosts:
Selfhost: you can find the MaxReceivedMessageSize setting on HttpSelfhostConfiguration
Webhost: You need to make couple of settings in case of this. You can take a look at my reply here for this: https://stackoverflow.com/a/17324840/1184056

Stop proxy server transforming HTTP POST to HTTP GET

I have a web app, which has a dashboard functionality. The app is used by many different companies in many different environments, all browsers.
There is a piece of javascript that refreshes that dashboard every 60 seconds via an http POST to a url which returns JSON.
For one user (and one user only according to my logs) the following .NET error message is generated every 60 seconds from that URL:
System.InvalidOperationException: This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.
at System.Web.Mvc.JsonResult.ExecuteResult(ControllerContext context)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass1c.<InvokeActionResultWithFilters>b__19()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass1c.<>c__DisplayClass1e.<InvokeActionResultWithFilters>b__1b()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
For all other users, there's never a problem.
I know for a fact that this user is on a network which is proxied (Government). This user is a new user - i.e. we've never had other users on this network.
The above leads me to believe that their proxy is modifying the request for some reason (attempted bandwidth optimisation?), converting the POST to a GET, silently. My Asp.NET MVC app is (correctly) refusing to honour the request for security reasons.
I'm unlikely to be able to change their proxy setup of course.
I tried adding the following to the action:
[OutputCache(Duration = 0, Location = OutputCacheLocation.None, NoStore=true)]
As well as:
Response.Cache.SetNoTransforms();
But the problem remains.
Are there any other HTTP headers that I can set to instruct the proxy to stop mangling things? Any other way of making these proxies behave? Or is there anything in a browser that might be doing this?
Update: since writing this, another 2 different users, from the same company, are now generating these errors, adding weight to my proxy theory.

Resources