ASP.NET requestValidation 4.5 и WIF - PullRequest
       4

ASP.NET requestValidation 4.5 и WIF

4 голосов
/ 16 марта 2012

У меня есть приложение 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.Как я могу это исправить?

Ответы [ 5 ]

18 голосов
/ 06 марта 2013

Обновите ваше приложение, чтобы использовать 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.

5 голосов
/ 20 марта 2012

Эудженио направил меня в правильном направлении.Но пример, на который он ссылается, больше не работает в ASP.NET 4.5.Как я уже прокомментировал его ответ, это приводит к переполнению стека.Это потому, что проверка запросов теперь выполняется, когда запрашиваются данные.Таким образом, проверка выполняется, когда WSFederationMessage.CreateFromFormPost запрашивает данные.Это вызывает наш запрос валидатора.И этот requestvalidator снова вызывает WSFederationMessage.CreateFromFormPost и так далее.После некоторого копания в коде WIF у меня теперь есть немного измененный requestvalidator, который работает.Вместо CreateFromFormPost мы используем CreateFromNameValueCollection (который также используется 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);
    }
}
3 голосов
/ 16 марта 2012

Да, это токен SAML, отправленный обратно из STS (ADFS) в вашем случае.Вы можете отключить валидацию, как предлагает Гаррет, или еще лучше, вы можете предоставить правильный валидатор, который понимает токены SAML, что очень легко сделать.

См. Этот другой вопрос / ответ: Потенциально опасный запрос. Форма в WSFederationAuthenticationModule.IsSignInResponse

0 голосов
/ 19 сентября 2014

Обратите внимание, что в режиме проверки запроса 4.5 у вас все еще может быть дополнительная работа, если ваш код на стороне сервера asp.net использует объект Request во время siginin (то есть, когда публикуется токен SAML).По умолчанию использование Request.Params генерируется при публикации токена SAML даже при включенном режиме проверки запроса 4.5.

0 голосов
/ 05 ноября 2012

У нас была та же проблема, но нам нужно, чтобы наш валидатор продолжал собираться под 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;
    }
}
...