我有一个ASP.NET MVC应用程序,启用了Windows Identity Foundation身份验证,ADFS为STS。 该应用程序现在在带有MVC 4的.NET 4.5上。 当我将ASP.NET requestValidation从2.0更改为4.5时,我收到此错误:
A potentially dangerous Request.Form value was detected from the client
(wresult="<t:RequestSecurityTo...").
我猜这是ADFS的重定向。 我怎样才能解决这个问题?
答案 0 :(得分:17)
升级您的应用程序以使用框架中包含的WIF 4.5:http://msdn.microsoft.com/en-us/library/jj157089.aspx
将RequestValidation设置为4.5模式:
<httpRuntime targetFramework="4.5" requestValidationMode="4.5" />
WIF 4.5与ASP.NET 4.5中的请求验证非常吻合。
答案 1 :(得分:4)
public class RequestValidator : System.Web.Util.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.CreateFromNameValueCollection(WSFederationMessage.GetBaseUrl(context.Request.Url), context.Request.Unvalidated.Form) as SignInResponseMessage != null)
{
return true;
}
}
return base.IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex);
}
}
答案 2 :(得分:3)
是的,这是您在案例中从STS(ADFS)发回的SAML令牌。你可以像Garrett建议的那样禁用验证,或者更好,你可以提供一个理解SAML令牌的合适验证器,这很容易做到。
请参阅此其他问题/答案:Potentially dangerous Request.Form in WSFederationAuthenticationModule.IsSignInResponse
答案 3 :(得分:0)
我们遇到了同样的问题,但我们的验证器需要继续针对4.0构建,以便它可以在4.0或4.5环境中使用,因此我们无法使用Jaap发布的解决方案。我们的解决方案是在HttpContext.Items中删除一个标记,让我们知道验证已在进行中,以便在触发嵌套验证时我们可以简单地让它通过。
public class WifRequestValidator : 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(AlreadyValidating(context))
{
return true; // Allows us to bypass check that happens as a result of trying to use context.Request.Form
}
StartValidating(context);
if (IsWsFedSigninResponse(context))
{
return true;
}
EndValidating(context);
}
return base.IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex);
}
private static bool AlreadyValidating(HttpContext context)
{
return context.Items["__ApprendaRequestValidatorInProgress"] != null;
}
private static void StartValidating(HttpContext context)
{
context.Items["__ApprendaRequestValidatorInProgress"] = new object();
}
private static bool IsWsFedSigninResponse(HttpContext context)
{
return WSFederationMessage.CreateFromFormPost(context.Request) as SignInResponseMessage != null;
}
private static void EndValidating(HttpContext context)
{
context.Items["__ApprendaRequestValidatorInProgress"] = null;
}
}
答案 4 :(得分:0)
注意,对于4.5请求验证模式,如果您的asp.net服务器端代码在siginin期间使用Request对象(即发布SAML令牌时),您可能还需要做一些额外的工作。 默认情况下,即使启用了4.5请求验证模式,也会在发布SAML令牌时使用Request.Params。