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>