In my MVC3 site I've avoided setting requestValidationMode="2.0" with the new ValidateInput attribute, but now I'm trying to switch to WIF for authentication, and when the STS redirects back to my site, I'm getting the exception because WSFederationAuthenticationModule.IsSignInResponse
is calling Request.Form
instead of Request.Unvalidated().Form
... is there any way to deal with this without going to requestValidationMode="2.0" (which I really don't want to do).
Here's the stack trace, so you can see what I mean. My Controller's method never really gets called.
[HttpRequestValidationException (0x80004005): A potentially dangerous Request.Form value was detected from the client (wresult="<trust:RequestSecuri...").]
System.Web.HttpRequest.ValidateString(String value, String collectionKey, RequestValidationSource requestCollection) +8755668
System.Web.HttpRequest.ValidateNameValueCollection(NameValueCollection nvc, RequestValidationSource requestCollection) +122
System.Web.HttpRequest.get_Form() +114
Microsoft.IdentityModel.Web.WSFederationAuthenticationModule.IsSignInResponse(HttpRequest request) +21
Microsoft.IdentityModel.Web.WSFederationAuthenticationModule.CanReadSignInResponse(HttpRequest request, Boolean onPage) +121
Microsoft.IdentityModel.Web.WSFederationAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs args) +78
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +148
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75
The correct way of dealing with this is to add specific validator to the HttpRuntime, that knows how to detect valid security tokens.
Look at any of the examples here: http://claimsid.codeplex.com/releases/view/62929
Here's an excerpt from one of those (sample #5 t be specific which is also an MVC app):
namespace FShipping
{
using System;
using System.Web;
using System.Web.Util;
using Microsoft.IdentityModel.Protocols.WSFederation;
public class WsFederationRequestValidator : RequestValidator
{
protected override bool IsValidRequestString(HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex)
{
validationFailureIndex = 0;
if (requestValidationSource == RequestValidationSource.Form &&
collectionKey.Equals(WSFederationConstants.Parameters.Result, StringComparison.Ordinal))
{
if (WSFederationMessage.CreateFromFormPost(context.Request) as SignInResponseMessage != null)
{
return true;
}
}
return base.IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex);
}
}
}
Here's the config:
<system.web>
...
<httpRuntime requestValidationType="FShipping.WsFederationRequestValidator" />
</system.web>
I think we also observed this same error at some point, but if I remember correctly that was in some experimental or test scaffolding code, so we didn't have a strict security requirement there.
The official information I could find is that this is a known issue in WIF: see the "ASP.NET Detects Passive Federation Tokens as Potential Security Attack" section at the beginning of the WIF Known Issues page. They say there to set validateRequest="false"
in web.config
, or the equivalent ASP.NET Page
directive for doing this at page level.
So you could try setting this only in a Page
directive on the 'home page' of your application, I'm not sure but that might work.
Note that they don't talk about requestValidationMode="2.0"
on the WIF Known Issues page, but judging from this TechNet wiki page this additional setting is necessary for ASP.NET 4.