0

場合によっては ADFS 認証を使用するプロジェクトがあります。構成はデータベースから読み取られ、URL は顧客ごとに異なるため、.com にハードコーディングできない多くの構成オプションがありますWeb.config

問題は、次のエラーが発生することです。

ID1032: AudienceUriMode が「Always」または「BearerKeyOnly」に設定されている場合、SamlSecurityTokenRequirement で少なくとも 1 つの「audienceUri」を指定する必要があります

しかし、私はいつもそれを得るわけではなく、再現することはできません. 再現できない限り、実際にデバッグすることはできないので、これはかなり面倒です。そして、私がすべて正しいことをしたかどうかはわかりません。たぶん、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.configSessionSecurityTokenHandler私のサービスは DNS ラウンド ロビン (同じマシン キーを共有する) を使用して複数のマシンで実行されるため、既定値を置き換える必要がありました。

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 でした。

4

1 に答える 1

0

例外には、audienceUri が必要であることが示されているため、最初に 1 つ下に追加します。

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

AudienceUri は、adfs がアプリケーションに返す Uri です。エンジンをオーバーライドして任意の戻り結果を受け入れることができますが、実際には構成に少なくとも 1 つの uri が必要であるという事実は変わりません。

于 2013-10-07T17:37:46.767 に答える