sharptooth sharptooth - 1 month ago 12
C# Question

Why is my controller action filter no longer invoked once I override SSL settings with a "location" element?

I have an ASP.NET MVC3 application with an action filter attribute applied to a controller:

public class MyFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(
ActionExecutingContext filterContext)
{
filterContext.HttpContext.Response.Headers.Add(
"MyFilterAttribute", "entered" );
}

public override void OnResultExecuted(
ResultExecutedContext filterContext)
{
filterContext.HttpContext.Response.Headers.Add(
"MyFilterAttribute", "exited" );
}
}

[MyFilter]
public class MyController : Controller
{
public ActionResult MyAction()
{
return new EmptyResult();
}
}


MVC routing maps
/MyPath/MyAction
to the controller-action pair above.

and the client code invokes
https://my.company.com/MyPath/MyAction
and dumps the response headers.

Initially it works - I see that the response received on the client contains two
MyFilterAttribute
headers as expected.

Then I add a
location
element to web.config:

<configuration>
// lots of stuff, then
<location path="MyPath">
<system.webServer>
<security>
<access sslFlags="SslNegotiateCert"/>
</security>
</system.webServer>
</location>
</configuration>


and once I redeploy with these changes the response headers no longer contain the two
MyFilterAttribute
items.

Adding
location
to web.config is the only change. Once I remove it the old expected behavior is back.

It looks like adding a
location
elements somehow breaks MVC attributes.

What might be causing this behavior?

Answer

sslFlags="SslNegotiateCert" requests that IIS opens a mutually verified channel which is not the default behavior. I looked into IIS logs and it's HTTP 403.16 (client certificate untrusted) all the time. Because the client certificate is self-signed IIS doesn't trust it and so fails to open a mutually verified channel.

Either I have to not use SslNegotiateCert (and then the client certificate is not passed to application code) or I need a certificate which IIS trusts (this answer explains how that can be achieved).