2012-03-16 3 views
3

У меня есть приложение ASP.NET MVC с проверкой подлинности Windows Identity Foundation с ADFS как STS. Теперь приложение на .NET 4.5 с MVC 4. Когда я изменить ASP.NET requestValidation от 2,0 до 4,5, я получаю эту ошибку:ASP.NET requestValidation 4.5 и WIF

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

Я думаю, это редирект с ADFS. Как я могу это исправить?

ответ

4

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

Спасибо @Jaap, ваш ответ спас мой день.Мы столкнулись с переполнением стека в другом сценарии на сайте 4.0. Это происходило, если это был кешированный STS-url. Я изменил функцию, как указано выше, чтобы исправить ее. Единственным отличием от выше было способ получить объект неопределенной формы как Request.Unvalidated.Form не был напрямую доступен в 4.0. var unvalidatedRequestFormValues ​​= System.Web.Helpers.Validation.Unvalidated (context.Request) .Form; – dreamerkumar

+0

Для любого пользователя на .net 4.5, выйдите из ответа @klings, просто установите targetFramework в 4.5 в элементе httpRuntime вашего web.config. – ctb

+0

@ctb, ответ королей тоже не работал на меня. У меня был аналогичный код, как указано выше, но он был для .Net 4.0, так же, как и Vishal. Мой код был перенесен на .Net 4.6 из .Net 4.0 и ответ здесь работал для меня. – ghanashyaml

3

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

Смотрите этот другой вопрос/ответ: Potentially dangerous Request.Form in WSFederationAuthenticationModule.IsSignInResponse

+0

Возможно, что-то изменилось в .NET 4.5 в отношении этого? Если я реализую этот requestvalidator, я получаю исключение переполнения стека, когда STS перенаправляет обратно. – Jaap

+0

Когда я удаляю вызов WSFederationMessage.CreateFromFormPost, он работает (но менее безопасен). Я полагаю, что stackoverflow является причиной того, что CreateFromFormPost снова запускает валидатор? – Jaap

+0

Теперь я помню, что где-то читал, что значения формы проверяются только при их запросе, теперь в ASP.NET 4.5. Поэтому я думаю, что проверка теперь срабатывает, когда WIF читает значение формы. Это вызывает проверку, которая, в свою очередь, снова заставляет WIF читать и т. Д. Поэтому этот пример больше не подходит для ASP.NET 4.5, я думаю. Есть ли другой способ проверить значение параметра формы wresult? – Jaap

0

У нас была такая же проблема, но необходимо для нашего валидатор продолжать строиться против 4.0, так что он может быть использован либо в 4.0 или 4.5 средах, поэтому мы не можем использовать решение, которое разместил Яп. Наше решение заключалось в том, чтобы пометить маркер в 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; 
    } 
} 
16

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

ЭТО! Если вы прочесываете сеть, как я, вы найдете идею установки requestValidationMode на 2.0 или или написание собственного валидатора. Это не было необходимо! Все, что мне было нужно, это установить целевую рамку на 4.5 (я даже не установил requestValidationMode), и это сработало. Ура! – ctb

+0

Я люблю правильные и легкие исправления! Спасибо, куча для обмена! –

0

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

Смежные вопросы