ASP.NET requestValidation 4.5和WIF

时间:2012-03-16 11:47:44

标签: asp.net wif

我有一个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的重定向。 我怎样才能解决这个问题?

5 个答案:

答案 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)

欧金尼奥引导我走向正确的方向。但是他所引用的示例在ASP.NET 4.5中不再起作用了。 正如我已经评论过他的回答,它导致了stackoverflow。这是因为请求验证现在在请求数据时完成。因此,当WSFederationMessage.CreateFromFormPost请求数据时,验证完成。这会触发我们的requestvalidator。此requestvalidator再次调用WSFederationMessage.CreateFromFormPost,依此类推。 在深入研究WIF代码之后,我现在有了一个稍微修改过的requestvalidator,它正在运行。我们使用CreateFromNameValueCollection(也由CreateFromFormPost使用)代替CreateFromFormPost,但现在我们可以使用Request.Unvalidated.Form来提供它。

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。