5

雖然解決了這個問題描述here,我創造了另一個,我似乎可以找到其他地方的網站:定製WIF請求驗證無限循環

SignInResponseMessage message = WSFederationMessage.CreateFromFormPost(context.Request) as SignInResponseMessage; 

上面的代碼一直稱爲IsValidRequestString(),這會導致一個無限循環。電話是一樣的,每次和堆棧看起來是這樣的:

> TestIdentityBroker.dll!TestIdentityBroker.Service.WsFederationRequestValidator.IsValidRequestString(System.Web.HttpContext context, string value, System.Web.Util.RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex) Line 19 C# 
[External Code] 
TestIdentityBroker.dll!TestIdentityBroker.Service.WsFederationRequestValidator.IsValidRequestString(System.Web.HttpContext context, string value, System.Web.Util.RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex) Line 19 + 0x21 bytes C# 
[External Code] 
TestIdentityBroker.dll!TestIdentityBroker.Service.WsFederationRequestValidator.IsValidRequestString(System.Web.HttpContext context, string value, System.Web.Util.RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex) Line 19 + 0x21 bytes C# 
[External Code] 
TestIdentityBroker.dll!TestIdentityBroker.Service.WsFederationRequestValidator.IsValidRequestString(System.Web.HttpContext context, string value, System.Web.Util.RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex) Line 19 + 0x21 bytes C# 
[External Code] 

這是在自定義的依賴是聯邦成員的身份從我的依賴方由FedUtil工具創建一個IP方安全令牌服務發生。有誰知道爲什麼WSFederationMessage.CreateFromFormPost()會調用請求驗證器?返回的混亂似乎很正常。

編輯:這隻發生在我已經被認證一次之前。如果我清除瀏覽器緩存,則不會發生。

<?xml version="1.0"?> 
<!-- 
    For more information on how to configure your ASP.NET application, please visit 
    http://go.microsoft.com/fwlink/?LinkId=152368 
    --> 
<configuration> 
    <configSections> 
    <section name="microsoft.identityModel" type="Microsoft.IdentityModel.Configuration.MicrosoftIdentityModelSection, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> 
    </configSections> 
    <connectionStrings> 
    <add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient" /> 
    </connectionStrings> 
    <appSettings> 
    <add key="webpages:Version" value="1.0.0.0" /> 
    <add key="ClientValidationEnabled" value="true" /> 
    <add key="UnobtrusiveJavaScriptEnabled" value="true" /> 
    <add key="FederationMetadataLocation" value="X:\WebTest\TestIdentityBroker\TestIdentityBroker_STS\FederationMetadata\2007-06\FederationMetadata.xml" /> 
    <add key="SigningCertificateName" value="CN=Dev4"/> 
    </appSettings> 
    <location path="FederationMetadata"> 
    <system.web> 
     <authorization> 
     <allow users="*" /> 
     </authorization> 
    </system.web> 
    </location> 
    <system.web> 
    <!--<authorization> 
     <deny users="?" /> 
    </authorization>--> 
    <compilation debug="true" targetFramework="4.0"> 
     <assemblies> 
     <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> 
     <add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> 
     <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> 
     <add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> 
     <add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> 
     <add assembly="Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> 
     </assemblies> 
    </compilation> 
    <!--<authentication mode="Forms"> 
     <forms loginUrl="~/Federation/Authenticate" timeout="2880" /> 
    </authentication>--> 
    <authentication mode="None" /> 
    <membership> 
     <providers> 
     <clear /> 
     <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" /> 
     </providers> 
    </membership> 
    <profile> 
     <providers> 
     <clear /> 
     <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/" /> 
     </providers> 
    </profile> 
    <roleManager enabled="false"> 
     <providers> 
     <clear /> 
     <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" /> 
     <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" /> 
     </providers> 
    </roleManager> 
    <pages> 
     <namespaces> 
     <add namespace="System.Web.Helpers" /> 
     <add namespace="System.Web.Mvc" /> 
     <add namespace="System.Web.Mvc.Ajax" /> 
     <add namespace="System.Web.Mvc.Html" /> 
     <add namespace="System.Web.Routing" /> 
     <add namespace="System.Web.WebPages" /> 
     </namespaces> 
    </pages> 
    <httpRuntime requestValidationType="TestIdentityBroker.Service.WsFederationRequestValidator" /> 
    <httpModules> 
     <add name="WSFederationAuthenticationModule" type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> 
     <add name="SessionAuthenticationModule" type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> 
     <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> 
     <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> 
    </httpModules> 
    </system.web> 
    <system.webServer> 
    <validation validateIntegratedModeConfiguration="false" /> 
    <modules runAllManagedModulesForAllRequests="true"> 
     <add name="WSFederationAuthenticationModule" type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler" /> 
     <add name="SessionAuthenticationModule" type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler" /> 
    </modules> 
    </system.webServer> 
    <runtime> 
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
     <dependentAssembly> 
     <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /> 
     <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" /> 
     </dependentAssembly> 
    </assemblyBinding> 
    </runtime> 
    <microsoft.identityModel> 
    <service> 
     <audienceUris> 
     <add value="https://rp_sts.local/" /> 
     <add value="https://rp_sts.local/Federation/LogOn" /> 
     </audienceUris> 
     <federatedAuthentication> 
     <wsFederation passiveRedirectEnabled="false" issuer="https://ip.local/" realm="https://rp_sts.local/" requireHttps="false" /> 
     <cookieHandler requireSsl="true" /> 
     </federatedAuthentication> 
     <applicationService> 
     <claimTypeRequired> 
      <!--Following are the claims offered by STS 'http://ip.local/'. Add or uncomment claims that you require by your application and then update the federation metadata of this application.--> 
      <claimType type="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" optional="true" /> 
      <claimType type="http://schemas.microsoft.com/ws/2008/06/identity/claims/role" optional="true" /> 
     </claimTypeRequired> 
     </applicationService> 
     <issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"> 
     <trustedIssuers> 
      <add thumbprint="xx" name="https://ip.local/" /> 
     </trustedIssuers> 
     </issuerNameRegistry> 
    </service> 
    </microsoft.identityModel> 
</configuration> 
+0

你能發佈web.config? – 2012-01-07 18:42:33

+0

當然,編輯。我通過在用戶已經通過身份驗證時在RP中添加了一個檢查來處理來自RP的聯合登錄請求的檢查,並且似乎解決了這個問題。但我很好奇發生了什麼。 – ryanhallcs 2012-01-09 15:57:45

+0

你如何保護動作/控制器?你是否起訴[授權]? – 2012-01-09 17:49:09

回答

0

在我的自定義的請求驗證(在配置設置):

<httpRuntime requestValidationType="TestIdentityBroker.Service.WsFederationRequestValidator" /> 

它試圖解決後成WIF消息,並且呼籲驗證功能,whcih導致了...堆棧溢出。

通過確保字段是WIF字段進行補救。

2

問題是,當用戶通過身份驗證時,訪問System.HttpContext.Current.Request在所有觸發器上執行RequestValidator。

所以傳遞System.HttpContext.Current.Request參考到WSFederationMessage.CreateFromFormPost內的RequestValidator發起無限循環。我沒有看到爲什麼會出現這個問題。

雖然你可以決定不處理你的STS已完成認證的用戶請求(像你一樣),如果你的代碼是依賴於其他發行人的中間STS不起作用。例如,如果請求RP通過不同的WHR,則在不同的家庭領域發出不同聲明的情況下,您仍然希望重新處理到您的父母STS。

在我來說,我是被迫的,如果有一個目前wresult參數只是返回true修改我的請求驗證。通過這樣做,責任來驗證進來的消息被委派到處理登入請求的代碼:

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)) 
     { 
      return true; 

      //SignInResponseMessage message = WSFederationMessage.CreateFromFormPost(context.Request) as SignInResponseMessage; 
      //if (message != null) 
      //{ 
       //return true; 
      //} 
     } 

     return base.IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex); 
    } 
} 
2

原來的Technet wiki page現在包含代碼的固定版本。 解決方案是在獲取POST數據的集合時顯式跳過驗證。

var unvalidatedFormValues = System.Web.Helpers.Validation.Unvalidated(context.Request).Form; 
SignInResponseMessage message = WSFederationMessage.CreateFromNameValueCollection(WSFederationMessage.GetBaseUrl(context.Request.Url), unvalidatedFormValues) as SignInResponseMessage; 

Validation類屬於System.Web.WebPages.dll組件,其通常與ASP.NET MVC一起安裝。

我不想我的實用工具庫MVC綁定,所以我看着Validation類反編譯器,並使用來自Microsoft.Web.Infrastructure.dll較低級別的方法,我已經提到:

var baseUrl = WSFederationMessage.GetBaseUrl(context.Request.Url); 
Func<NameValueCollection> formGetter, queryStringGetter; 
Microsoft.Web.Infrastructure.DynamicValidationHelper.ValidationUtility.GetUnvalidatedCollections(context, out formGetter, out queryStringGetter); 
if (WSFederationMessage.CreateFromNameValueCollection(baseUrl, formGetter()) is SignInResponseMessage) 
    return true;