ASP.NET requestValidation 4.5 and WIF



我有一个ASP.NET MVC应用程序,它启用了Windows Identity Foundation身份验证,ADFS作为STS。该应用程序现在在.NET 4.5上使用MVC 4。当我将ASP.NET requestValidation从2.0更改为4.5时,我会得到以下错误:

A potentially dangerous Request.Form value was detected from the client 
(wresult="<t:RequestSecurityTo...").

我想这是来自ADFS的重定向。我该怎么解决这个问题?

升级您的应用程序以使用框架中包含的WIF 4.5:http://msdn.microsoft.com/en-us/library/jj157089.aspx

将RequestValidation设置为4.5模式:

<httpRuntime targetFramework="4.5" requestValidationMode="4.5" />

WIF4.5可以很好地处理ASP.NET 4.5中的请求验证。

Eugenio引导我走向正确的方向。但他所指的示例在ASP.NET 4.5中已不起作用。正如我已经对他的回答所评论的那样,这导致了一种堆叠式的流动。这是因为请求验证现在是在请求数据时完成的。因此,验证是在WSFederationMessage.CreateFromFormPost请求数据时完成的。这会触发我们的请求验证器。此请求验证器再次调用WSFederationMessage.CreateFromFormPost,依此类推。在对WIF代码进行了一些挖掘之后,我现在有了一个经过轻微修改的requestvalidator,它正在工作。我们使用CreateFromNameValueCollection(CreateFromFormPost也使用它)而不是CreateFromFormPost,但现在我们可以用Request.Unvalided.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);
    }
}

是的,这是从STS(ADFS)返回的SAML令牌。你可以按照Garrett的建议禁用验证,或者更好的是,你可以提供一个理解SAML令牌的合适的验证器,这很容易做到

请参阅其他问题/答案:WSFederationAuthenticationModule.IsSignInResponse 中的潜在危险请求表单

我们也遇到了同样的问题,但需要我们的验证器继续针对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.5请求验证模式下,如果您的asp.net服务器端代码在siginin期间(即发布SAML令牌时)使用request对象,您可能还有一些额外的工作要做。默认情况下,即使在4.5请求验证模式打开的情况下,发布SAML令牌时也会抛出Request.Params。

相关内容

  • 没有找到相关文章

最新更新