Determine if a HTTP request is a soap request on HttpApplication.AuthenticateRequest - asp.net

I there a way to know if a request is a soap request on AuthenticateRequest event for HttpApplication? Checking ServerVariables["HTTP_SOAPACTION"] seems to not be working all the time.
public void Init(HttpApplication context) {
context.AuthenticateRequest += new EventHandler(AuthenticateRequest);
}
protected void AuthenticateRequest(object sender, EventArgs e) {
app = sender as HttpApplication;
if (app.Request.ServerVariables["HTTP_SOAPACTION"] != null) {
// a few requests do not enter here, but my webservice class still executing
// ...
}
}
I have disabled HTTP POST and HTTP GET for webservices in my web.config file.
<webServices>
<protocols>
<remove name="HttpGet" />
<remove name="HttpPost" />
<add name="AnyHttpSoap" />
</protocols>
</webServices>
Looking at ContentType for soap+xml only partially solves my problem. For example,
Cache-Control: no-cache
Connection: Keep-Alive
Content-Length: 1131
Content-Type: text/xml
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: ro
Host: localhost
mymethod: urn:http://www.wsnamespace.com/myservice
Some clients instead of having the standard header SOAPAction: "http://www.wsnamespace.com/myservice/mymethod", have someting like in example above. "mymethod" represents the method in my web service class with [WebMethod] attribute on it and "http://www.wsnamespace.com/myservice" is the namespace of the webservice. Still the service works perfectly normal.
The consumers use different frameworks (NuSOAP from PHP, .NET, Java, etc).

You could look at Request.ContentType property, which if properly set by the client should be
application/soap+xml; charset=utf-8
The utf-8 part may not be present.
Aside from that, surely you can just check the URL, and if it's a webservice one then that tells you what it is.

I always give web services their own port. That way I don't have to filter every HTTP request that comes across port 80. Or rather, I can filter port 80 for browser-oriented issues, and SOAP/SOA ports for other types of attacks.
IMAO, mixing (potentially) sensitive business data with public data just so you don't have to open another hole in the firewall is thumbing your nose at the very reason you have a firewall in the first place.

You could also go down the harder route and figure things out based on everything else that's below HTTP headers. What I mean by that is, to analyze things like below, which is the SOAP request body - part of the request...
<soap:Envelope xmlns:soap="..." soap:encodingStyle="...">
IBM

Have you tested the System.Web.HttpContext.Current.Request.CurrentExecutionFilePathExtension ??
Normally this would be .asmx for webservices (json and xml), as long as you handle the service of course.

I am using following code to identify the request type. Try this if it match your requirment. Mark as answer if it help you.
if (request.Headers["SOAPAction"] != null || request.ContentType.StartsWith("application/soap+xml"))
return ServiceRequestTypes.SoapRequest;
else if ("POST".Equals(request.RequestType, StringComparison.InvariantCultureIgnoreCase) && request.ContentType.StartsWith("application/x-www-form-urlencoded", StringComparison.InvariantCultureIgnoreCase))
return ServiceRequestTypes.HttpPostRequest;
else if ("POST".Equals(request.RequestType, StringComparison.InvariantCultureIgnoreCase) && request.ContentType.StartsWith("application/json", StringComparison.InvariantCultureIgnoreCase))
return ServiceRequestTypes.AjaxScriptServiceRequest;
return ServiceRequestTypes.Unknown;

Related

adding cors to aspx web api 2 hybrid

I've added Web API 2 to an existing vb aspx web forms project. and the routing went into the global asax application_start because I do not have an app_start folder with WebApiConfig as you do in a standard web api project. I downloaded CORS from the nugget package manager add attempted to enable CORS
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
' Fires when the application is started
RouteTable.Routes.MapHttpRoute(
name:="DefaultApi",
routeTemplate:="api/{controller}/{id}",
defaults:=New With {.id = RouteParameter.Optional}
)
Dim cors = New EnableCorsAttribute("*", "*", "*")
GlobalConfiguration.Configuration.EnableCors(cors)
End Sub
however whenever I attempt to run an html page that is making calls to my web api through jquery ajax I receive.
Cross-Origin Request Blocked: The Same Origin Policy
disallows reading the remote resource at https://xxxxx/specialdev/api/WSFobOrigin.
(Reason: CORS header 'Access-Control-Allow-Origin' missing)
So I'm not quite sure what I am missing I attempting adding it to each controller as well.
Public Class WSFobOriginController
Inherits ApiController
<EnableCors("*", "*", "*")>
<HttpGet>
<CustomAuthentication>
<Authorize(Roles:="WebService")>
Public Function logon() As IHttpActionResult
Return Ok("successfully loggon on")
End Function
Here is the ajax call (I tried it with and without the crossDomain: true)
this.logon = function () {
$('#signin').prop('disabled', true);
$.ajax({
url: "https://xxxxxxxx.dir.ad.dla.mil/specialdev/api/WSFobOrigin",
type: "GET",
datatype: "json",
crossDomain: true,
beforeSend: function (xhr) {
$('#logonSpinner').show();
xhr.setRequestHeader("Authorization", "Basic " + btoa(self.userName() + ":" + self.password()));
},
success: function (data) {
self.loggedon(true);
},
error: function (xhr, status, error) {
$('#signin').prop('disabled', false);
$('#logonSpinner').hide();
$('#logonError').show();
self.logOnErrorMessage("Status: " + xhr.status + " Message: " + xhr.statusText)
}
});
}
just noticed one more thing that is a bit odd to me. when I run the web api locally (through visual studio) and change my client jquery ajax call to the local url it works.
URL Protocol Method Result Type Received Taken Initiator Wait‎‎ Start‎‎ Request‎‎ Response‎‎ Cache read‎‎ Gap‎‎
http://localhost:52851/api/WSFobOrigin HTTP OPTIONS 200 420 B 31 ms CORS Preflight 0 16 0 15 0 203
and
URL Protocol Method Result Type Received Taken Initiator Wait‎‎ Start‎‎ Request‎‎ Response‎‎ Cache read‎‎ Gap‎‎
http://localhost:52851/api/WSFobOrigin HTTP GET 200 application/json 447 B 218 ms XMLHttpRequest 16 15 203 0 0 0
but when I change the client to point to the actual server the preflight aborts and the type no longer says OPTIONS it is null
URL Protocol Method Result Type Received Taken Initiator Wait‎‎ Start‎‎ Request‎‎ Response‎‎ Cache read‎‎ Gap‎‎
https://xxxxxxx.dir.ad.dla.mil/specialdev/api/WSFobOrigin HTTPS (Aborted) 0 B 47 ms CORS Preflight 0 47 0 0 0 796
some other posts had suggested adding a filter which I tried but that does not seem to work either
Imports System.Web.Http.Filters
Public Class AllowCors
Inherits ActionFilterAttribute
Public Overrides Sub OnActionExecuted(actionExecutedContext As HttpActionExecutedContext)
If actionExecutedContext Is Nothing Then
Throw New ArgumentNullException("actionExecutedContext")
Else
actionExecutedContext.Response.Headers.Remove("Access-Control-Allow-Origin")
actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin", "*")
actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type")
actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Methods", "GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS")
End If
MyBase.OnActionExecuted(actionExecutedContext)
End Sub
End Class
and decorating my controller with allowcors
<AllowCors>
<EnableCors("*", "*", "*")>
<HttpGet>
<CustomAuthentication>
<Authorize(Roles:="WebService")>
Public Function logon() As IHttpActionResult
Return Ok("successfully loggon on")
End Function
but still no luck
status: 404
Method: OPTIONS
Request Headers: Host: xxxxxx.dir.ad.dla.mil
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: null
Access-Control-Request-Method: GET
Access-Control-Request-Headers: authorization
Connection: keep-alive
Response Headers: Cache-Control: private
Content-Type: text/html
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
X-Frame-Options: SAMEORIGIN
Date: Wed, 23 Mar 2016 16:53:06 GMT
Content-Length: 1245
You can configure CORS support for the Web API at three levels:
At the Global level
At the Controller level
At the Action level
To configure CORS support at the global level,
first install the CORS package (Which you already did)
and then open WebApiConfig.cs file from App_Start folder.(here you said you dont have that folder)
Dim cors = New EnableCorsAttribute("http://localhost:5901", "*", "*")
config.EnableCors(cors)
(As you are not using that method, then we will go to next Level)
Action Level
<EnableCors(origins := "*", headers := "*", methods := "*")>
<HttpGet>
<CustomAuthentication>
<Authorize(Roles:="WebService")>
Public Function logon() As IHttpActionResult
Return Ok("successfully loggon on")
End Function
In the above method you need to set parameters to allow all the headers and support all the HTTP methods by setting value to star.
Controller Level
<EnableCors(origins := "*", headers := "*", methods := "*")> _
Public Class ClassesController
Inherits ApiController
End Class
In this you need to set parameters to allow all the headers and support all the HTTP methods by setting value to star. you can exclude one of the actions from CORS support using the [DisableCors] attribute.
So finally Here are the Attributes of EnableCors
There are three attributes pass to EnableCors:
Origins: You can set more than one origins value separated by commas. If you want any origin to make AJAX request to the API then set origin value to wild card value star.
Request Headers: The Request header parameter specifies which Request headers are allowed. To allow any header set value to *
HTTP Methods: The methods parameter specifies which HTTP methods are allowed to access the resource. To allow all methods, use the wildcard value '*'. Otherwise set comma separated method name to allow set of methods to access the resources.
So combining above points in VB you need to Declare as below
<EnableCors(origins := "http://localhost:XXX,http://localhost:YYYY", headers := "*", methods := "POST,GET")> _
Public Class ClassesController
Inherits ApiController
End Class
Update
Try to Add this Config to your web-config
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, PUT, POST, DELETE, HEAD, OPTIONS" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" />
<add name="Access-Control-Allow-Headers" value="Content-Type, Accept, Authorization" />
</customHeaders>
I think you forgot adding Microsoft.AspNet.Cors. If you use Visual Studio, you can add use this way:
Tools-> Nuget Package Manager ->Manage Nuget Packages for Solutions
You should find Microsoft.AspNet.Cors and install to api project

Web API as a Proxy and Chunked Transfer Encoding

I have been playing around with using Web API (Web Host) as a proxy server and have run into an issue with how my Web API proxy handles responses with the "Transfer-Encoding: chunked" header.
When bypassing the proxy, the remote resource sends the following response headers:
Cache-Control:no-cache
Content-Encoding:gzip
Content-Type:text/html
Date:Fri, 24 May 2013 12:42:27 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/8.0
Transfer-Encoding:chunked
Vary:Accept-Encoding
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
When going through my Web API based proxy, my request hangs unless I explicitly reset the TransferEncodingChunked property on the response header to false:
response.Headers.TransferEncodingChunked = false;
I admit, I don't fully understand what impact setting the TransferEncodingChunked property has, but it seems strange to me that in order to make the proxy work as expected, I need to set this property to false when clearly the incoming response has a "Transfer-Encoding: chunked" header. I am also concerned about side effects to explicitly setting this property. Can anyone help me understand what is going on and why setting this property is required?
UPDATE: So I did a little more digging into the difference in the response when going through the proxy vs. not. Whether I explicitly set the TransferEncodingChunked property to false, the response headers when coming through the proxy are exactly the same as when not going through the proxy. However, the response content is different. Here are a few samples (I turned off gzip encoding):
// With TransferEncodingChunked = false
2d\r\n
This was sent with transfer-encoding: chunked\r\n
0\r\n
// Without explicitly setting TransferEncodingChunked
This was sent with transfer-encoding: chunked
Clearly, the content sent with TransferEncodingChunked set to false is in fact transfer encoded. This is actually the correct response as it is what was received from the requested resource behind the proxy. What continues to be strange is the second scenario in which I don't explicitly set TransferEncodingChunked on the response (but it is in the response header received from the proxied service). Clearly, in this case, the response is NOT in fact transfer encoded by IIS, in spite of the fact that the actual response is. Strange...this is starting to feel like designed behavior (in which case, I'd love to know how / why) or a bug in IIS, ASP.Net, or Web API.
Here is a simplified version of the code I am running:
Proxy Web API application:
// WebApiConfig.cs
config.Routes.MapHttpRoute(
name: "Proxy",
routeTemplate: "{*path}",
handler: HttpClientFactory.CreatePipeline(
innerHandler: new HttpClientHandler(), // Routes the request to an external resource
handlers: new DelegatingHandler[] { new ProxyHandler() }
),
defaults: new { path = RouteParameter.Optional },
constraints: null
);
// ProxyHandler.cs
public class ProxyHandler : DelegatingHandler
{
protected override async System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
// Route the request to my web application
var uri = new Uri("http://localhost:49591" + request.RequestUri.PathAndQuery);
request.RequestUri = uri;
// For GET requests, somewhere upstream, Web API creates an empty stream for the request.Content property
// HttpClientHandler doesn't like this for GET requests, so set it back to null before sending along the request
if (request.Method == HttpMethod.Get)
{
request.Content = null;
}
var response = await base.SendAsync(request, cancellationToken);
// If I comment this out, any response that already has the Transfer-Encoding: chunked header will hang in the browser
response.Headers.TransferEncodingChunked = false;
return response;
}
}
And my web application controller which creates a "chunked" response (also Web API):
public class ChunkedController : ApiController
{
public HttpResponseMessage Get()
{
var response = Request.CreateResponse(HttpStatusCode.OK);
var content = "This was sent with transfer-encoding: chunked";
var bytes = System.Text.Encoding.ASCII.GetBytes(content);
var stream = new MemoryStream(bytes);
response.Content = new ChunkedStreamContent(stream);
return response;
}
}
public class ChunkedStreamContent : StreamContent
{
public ChunkedStreamContent(Stream stream)
: base(stream) { }
protected override bool TryComputeLength(out long length)
{
length = 0L;
return false;
}
}
From an HttpClient standpoint, content chunking is essentially a detail of the transport. The content provided by response.Content is always de-chunked for you by HttpClient.
It looks like there's a bug in Web API that it doesn't correctly (re-)chunk content when requested by the response.Headers.TransferEncodingChunked property when running on IIS. So the problem is that the proxy is telling the client, via the headers, that the content is chunked when in fact it is not. I've filed the bug here:
https://aspnetwebstack.codeplex.com/workitem/1124
I think your workaround is the best option at the moment.
Also notice that you have multiple layers here that likely weren't designed/tested for proxying scenarios (and may not support it). On the HttpClient side, note that it will automatically decompress and follow redirects unless you turn that behavior off. At a minimum, you'll want to set these two properties:
http://msdn.microsoft.com/en-us/library/system.net.http.httpclienthandler.allowautoredirect.aspx
http://msdn.microsoft.com/en-us/library/system.net.http.httpclienthandler.automaticdecompression.aspx
On the WebApi/IIS side, you've found at least one bug, and it wouldn't be suprising to find others as well. Just be forewarned there may be bugs like this currently writing a proxy using these technologies outside their main design use cases.

JQuery consuming ASP.Net Web Service webserver - Request format is unrecognized for URL unexpectedly ending in

Done a lot of Googling on this but cant seem to find an answer.
When I call my web service from Jquery I am receiving the error
Request format is unrecognized for URL unexpectedly ending in '/AirportSearchGeneric'.
Factors
I am currently calling a webservice that is on the same machine but on a different webserver (calling app is port 64004 and receiving app is 1400) - possible cross "domain" issue? Both are local host.
Both are using the test web server that is part of visual studio.
I have tried adding the 2 protocols to the web.config (add name="HttpGet" add name="HttpPost")
The error occures in the Event Viewer on the server.
I get the following in Firebug...
OPTIONS AirportSearchGeneric
http://localhost:1400/services/airportservice.asmx/AirportSearchGeneric
500 Internal Server Error
localhost:1400
... not seen OPTIONS before but the request is being accessed with a POST request.
JQuery code...
$.ajax({
type: "POST",
url: "http://localhost:1400/services/airportservice.asmx/AirportSearchGeneric",
data: "{'criteria':'EGBB', 'maxResults':'10'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
alert(msg.d);
}
});
Web service code...
[WebService(Namespace = "http://localhost/WebServices")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class AirportService : WebService
{
[WebMethod]
[ScriptMethod(ResponseFormat=ResponseFormat.Json)]
public string AirportSearchGeneric(string criteria, int maxResults)
{
IAirportService svc = new Airports.AirportService.AirportService();
List<AirportSearchResult> res = svc.AirportSearchGeneric(criteria, maxResults);
DataContractJsonSerializer serializer = new DataContractJsonSerializer(res.GetType());
MemoryStream ms = new MemoryStream();
serializer.WriteObject(ms, res);
string jsonString = Encoding.Default.GetString(ms.ToArray());
ms.Close();
return jsonString;
}
}
... dont think its a problem in here as when debugging, no code in here gets executed.
Pretty sure I have covered off all of the reasons I have read as to why this occurs so would be greatful for any advice on how I can get this working.
Cheers.
For reference the firebug headers are as follows:
Host localhost:1400
User-Agent Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12 ( .NET CLR 3.5.30729; .NET4.0E)
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language en-gb,en;q=0.5
Accept-Encoding gzip,deflate
Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive 115
Connection keep-alive
Origin http://localhost:64004
Access-Control-Request-Me... POST
(No response is received in firebug apart from the 500 error, there is no html response at all).
Using different ports on the same machine is considered cross domain and not allowed by the browser as you were suspecting.
You either call the other port by tricking the browser using JSONP (if can limit yourself to only using GET requests) or change one of the ports to be the same as the other.
Ajax Cross Domain Calls

HTTP Compression: Some external scripts/CSS not decompressing properly some of the time

I am implementing page/resource compression to improve website performance.
I have tried to implement both blowery and wicked HttpCompress but end up getting the same result. This only seems to affect Firefox, I have tested on Chrome and IE.
What happens is the first time I request the page all the external resources decompress ok. The 2nd or 3rd time the page has errors because the resource doesn't seem to be decompressed. I get unicode characters like:
������í½`I%&/mÊ{JõJ×àt¡`$Ø#ìÁÍæìiG#)«*ÊeVe]f
(actually they can't be displayed properly here)
Inspecting the page via firebug displays the response header as:
Cache-Control private
Content-Type text/html; charset=utf-8
Content-Encoding gzip
Server Microsoft-IIS/7.5
X-AspNetMvc-Version 2.0
X-AspNet-Version 2.0.50727
X-Compressed-By HttpCompress
X-Powered-By ASP.NET Date Fri, 09 Jul
2010 06:51:40 GMT Content-Length 2622
This clearly states that the resource is compressed by gzip. So something seems to be going wrong on the deflate side on the client?
I have added the following sections (in the appropriate locations) in the web.config:
<sectionGroup name="blowery.web">
<section name="httpCompress" type="blowery.Web.HttpCompress.SectionHandler, blowery.Web.HttpCompress"/>
</sectionGroup>
<blowery.web>
<httpCompress preferredAlgorithm="gzip" compressionLevel="high">
<excludedMimeTypes>
<add type="image/jpeg"/>
<add type="image/png"/>
<add type="image/gif"/>
</excludedMimeTypes>
<excludedPaths>
<add path="NoCompress.aspx"/>
</excludedPaths>
</httpCompress>
</blowery.web>
<add name="CompressionModule" type="blowery.Web.HttpCompress.HttpModule, blowery.web.HttpCompress"/>
Any help?
This is an issue that I have face before and the problem is that the Content-Length is not correct. Why is not correct ? because its probably calculate before the compression.
If you set Content-Lenght by hand, just remove it and let the module set it if he can.
I note that you use the Blowery compression. Probably this is a bug/issue inside Blowery. If you can not locate it and fix it, why not use the Ms compression ?
#ptutt if you are on shared iis, then maybe there have all ready set compression, so there is one compression over the other, and you only need to remove yours. If this is the issue then for sure the content-lenght is false because after the first compression, the second is break it.
Check it out using this site https://www.giftofspeed.com/gzip-test/ if your pages is all ready compressed by default by iis.
If not compressed by default then you can do it very easy. On Global.asax
protected void Application_BeginRequest(Object sender, EventArgs e)
{
string cTheFile = HttpContext.Current.Request.Path;
string sExtentionOfThisFile = System.IO.Path.GetExtension(cTheFile);
if (sExtentionOfThisFile.Equals(".aspx", StringComparison.InvariantCultureIgnoreCase))
{
string acceptEncoding = MyCurrentContent.Request.Headers["Accept-Encoding"].ToLower();;
if (acceptEncoding.Contains("deflate") || acceptEncoding == "*")
{
// defalte
HttpContext.Current.Response.Filter = new DeflateStream(prevUncompressedStream,
CompressionMode.Compress);
HttpContext.Current.Response.AppendHeader("Content-Encoding", "deflate");
} else if (acceptEncoding.Contains("gzip"))
{
// gzip
HttpContext.Current.Response.Filter = new GZipStream(prevUncompressedStream,
CompressionMode.Compress);
HttpContext.Current.Response.AppendHeader("Content-Encoding", "gzip");
}
}
}
Please note, I just write this code and have not tested. My code is a little more complicate, so I just create a simple verion of it.
Find more examples:
http://www.google.com/search?q=Response.Filter+GZipStream
Reference:
ASP.NET site sometimes freezing up and/or showing odd text at top of the page while loading, on load balanced servers

How to log HTTP requests coming into IIS

I run IIS 5 on my dev machine. I have an asp.net 3.5 web service running on it which I'm calling from a different web app running on the same server. My service is returning an error 500 Internal Server error and I'm troubleshooting it. My request is being sent via a System.Net.HttpWebRequest object and it looks valid from the client's perspective.
I'd like to see the raw incoming HTTP request from the server's perspective. Since the service is being called on loopback, I can't use Wireshark to see it.
IIS Logging shows me the request header but not the post content.
Any suggestions on how I could see the full raw incoming HTTP request in IIS?
Thanks
I would think you want to add an HTTPModule for logging. Here's a pretty good article on ASP.NET modules and handlers:
That way, when you want to disable logging, you can just remove/comment it from your web.config file.
Have you tried using Fiddler? Just use your machine name instead of localhost.
Your best bet is to run each of your web apps on a different port, and then use something like Fiddler to create a proxy for the port you want to watch. This will monitor all traffic to and from your specific application.
Here is code of custom HTTP module we use to log HTTP POST request data.
using System;
using System.Web;
namespace MySolution.HttpModules
{
public class HttpPOSTLogger : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
}
private void context_BeginRequest(object sender, EventArgs e)
{
if (sender != null && sender is HttpApplication)
{
var request = (sender as HttpApplication).Request;
var response = (sender as HttpApplication).Response;
if (request != null && response != null && request.HttpMethod.ToUpper() == "POST")
{
var body = HttpUtility.UrlDecode(request.Form.ToString());
if (!string.IsNullOrWhiteSpace(body))
response.AppendToLog(body);
}
}
}
}
}
Do not forget to register it in web.config of you application.
Use system.WebServer section for IIS Integrated Model
<system.webServer>
<modules>
<add name="HttpPOSTLogger" type="MySolution.HttpModules.HttpPOSTLogger, MySolution.HttpModules" />
</modules>
</system.webServer>
Use system.web section for IIS Classic Model
<system.web>
<httpModules>
<add name="HttpPOSTLogger" type="MySolution.HttpModules.HttpPOSTLogger, MySolution.HttpModules"/>
</httpModules>
</system.web>
IIS log Before applying module:
::1, -, 10/31/2017, 10:53:20, W3SVC1, machine-name, ::1, 5, 681, 662, 200, 0, POST, /MySolution/MyService.svc/MyMethod, -,
IIS log After applying module:
::1, -, 10/31/2017, 10:53:20, W3SVC1, machine-name, ::1, 5, 681, 662, 200, 0, POST, /MySolution/MyService.svc/MyMethod, {"model":{"Platform":"Mobile","EntityID":"420003"}},
Full article:
https://www.codeproject.com/Tips/1213108/HttpModule-for-logging-HTTP-POST-data-in-IIS-Log
I'm able to log request/response with many data (request body included for http post etc...), all http verbs included (ex: get, post) using IIS Failed Request Tracing
The request does not necessarily needs to fail to be logged as you can specify there any http status like 200, 401 etc or just all (enter 100-999).
You can also just log requests with a specific URL
I'll later implement a custom http module for more control.
Thanks

Resources