2013-10-07 104 views
0

我有一個在某些情況下使用ADFS身份驗證的項目。配置是從數據庫中讀取的,URLs不同於客戶,因此有很多配置選項,我不能在我的Web.config中進行硬編碼。有時ADFS例外:ID1032「至少必須指定一個'audienceUri'...」

的問題是,我得到以下錯誤:

ID1032: At least one 'audienceUri' must be specified in the SamlSecurityTokenRequirement when the AudienceUriMode is set to 'Always' or 'BearerKeyOnly'

但我不明白這一點一如既往,我不能複製。這很煩人,因爲只要我不能重現它,我就無法真正調試它。而且我不確定我是否做了一切正確的事情。也許一些ADFS專家可以看看它。

(我靠當事人及其相應的ADFS服務器之間的信任關係已經建立,當然)。

這裏是我的代碼(只有它的有趣的部分),請詢問是否有任何遺漏或不清楚。

從我Web.config一些片段:

<system.webServer> 
    <modules> 
    <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" /> 
    <add name="ClaimsPrincipalHttpModule" type="Microsoft.IdentityModel.Web.ClaimsPrincipalHttpModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler" /> 
    <!-- ... --> 
    </modules> 
    <!-- ... --> 
</system.webServer> 
<microsoft.identityModel> 
    <service> 
    <securityTokenHandlers> 
     <remove type="Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler" /> 
     <add type="MyProject.MachineKeySessionSecurityTokenHandler" /> 
    </securityTokenHandlers> 
    <federatedAuthentication> 
     <wsFederation passiveRedirectEnabled="false" 
        issuer="https://fail/IssuerEndpoint" 
        realm="https://fail/FederationResult" 
        homeRealm="https://fail" 
        requireHttps="true" /> 
    </federatedAuthentication> 
    </service> 
</microsoft.identityModel> 

那些失敗值在每次請求被覆蓋(請參閱我的Login()方法如下圖),但我有我的Web.config指定的東西,所以我至少選擇指定一個有效的URI。由於我的服務使用DNS Round-Robin(共享相同的機器密鑰)在多臺機器上運行,因此必須更換默認的SessionSecurityTokenHandler

然後我有一個叫做AdfsTrustFilter的課程,它實現了IAuthorizationFilter。我知道這是一些開銷,但由於項目結構,這個過濾器被用作每個請求的全局過濾器(訂單是整個項目中最小的值)。在OnAuthorization方法,我完成配置如下:

public sealed class AdfsTrustFilter : IAuthorizationFilter 
    public void OnAuthorization(AuthorizationContext filterContext) 
     // ... 

     var fam = FederatedAuthentication.WSFederationAuthenticationModule; 

     fam.ServiceConfiguration = new ServiceConfiguration 
     { 
      AudienceRestriction = new AudienceRestriction(AudienceUriMode.Always), 
      CertificateValidationMode = X509CertificateValidationMode.PeerOrChainTrust, 
      // MyIssuerNameRegistry checks whether a fingerprint is known and some other stuff 
      IssuerNameRegistry = new MyIssuerNameRegistry() 
     }; 

     // config.OwnPath contains something like "https://my.app.com/AppRoot/" 
     fam.ServiceConfiguration.AudienceRestriction.AllowedAudienceUris.Add(new Uri(config.OwnPath)); 
    } 
} 

這是啓動驗證碼:

public ActionResult Login() 
{ 
    // ... 

    // again something like "https://my.app.com/AppRoot/" 
    string baseUrl = Config.OwnPath.TrimEnd('/') + "/"; 

    // adfs endpoint for this customer: i.e. "https://identity.provider.net/adfs/ls/" 
    string endpoint = Config.AdfsConfig.IdentityProvider.Endpoint; 

    // the code behind FederationResult is shown below 
    var signIn = new SignInRequestMessage(new Uri(endpoint), baseUrl + "/Adfs/FederationResult") 
         { 
          Context = baseUrl 
         }; 

    var url = signIn.WriteQueryString(); 

    return Redirect(url); 
} 

最後的FederationResult回調:

public ActionResult FederationResult() 
{ 
    WSFederationAuthenticationModule fam = FederatedAuthentication.WSFederationAuthenticationModule; 
    HttpRequest request = System.Web.HttpContext.Current.Request; 

    if (fam.CanReadSignInResponse(request, true)) 
    { 
     var id = (IClaimsIdentity) User.Identity; 

     // do something 
    } 

    // ... 
} 

PS: ADFS服務器最近從2008 R2升級到2012年,但這並沒有改變任何東西。 ADFS版本始終爲2.0。

回答

0

由於異常說,你需要的audienceUri,我會通過添加一個下

<microsoft.IdentityModel> 
    <service> 
     <audienceUris> 
      <add value="https://yourdomain/theaudienceuri" /> 

的audienceUri是URI ADFS返回到您的應用程序啓動。您可以重寫引擎以接受任意返回結果,這不會改變事實,即在配置中確實需要至少一個uri。

+0

一個好主意(我會嘗試它),但爲什麼大多數情況下它會在沒有配置的受衆URI的情況下工作?此時,我僅通過代碼設置了觀衆URI,僅在一段時間內只發生了這種異常。 – fero

+0

偉大的問題,聽起來像authorizaiton過濾器有時不起作用?沒有更深入的調試,我想不出一個明顯的原因。 –

相關問題