2

私は、TFSの一部であり、開発チームによって使用されているasp.netWebアプリケーションに取り組んでいます。最近、プロジェクトの一環としてADFSをセットアップし、ADFSサーバーへのプロジェクトの認証を強制しようとしています。

私の開発マシンでは、フェデレーションメタデータを生成するSTS参照を追加する手順と、プロジェクトのweb.configファイルを更新する手順を実行しました。web.config内の認証では、指紋認証を使用します。これにより、ローカルマシンにADFS証明書を追加し、開発マシンの署名付き証明書を生成してADFSに追加する必要があります。

すべてがセットアップされて機能していますが、web.configを確認しています。およびFederationMetadata.xmlは、これらがマシン固有であるように「見える」ことを文書化しています。プロジェクト/ファイルをTFSにチェックインすると、ビルドを実行する次の開発者またはテスターは、マシン上でビルドが壊れてしまうのではないかと思います。

私の質問はTFS内で、このようなシナリオをチェックインし、チームが開発環境またはテスト環境で最新のコードを使用してプロジェクトをチェックアウト、ビルド、およびテストできるようにするためのプロセスは何ですか?

現時点での私の回避策は、FederationMetaData.xmlとweb.configをチェックインから除外し、各開発マシンでADFS認証と製品テストを手動でセットアップすることです。完了すると、各ユーザーは、FederationMetatData.xmlとweb.configのローカルコピーがチェックインされないようにすることができます(別名、独自のローカルコピーがあります)。チェックイン/チェックアウトするときは、各開発者が自分のコピーを保持することを確認してください(または保持しない)それらをTFSにチェックインします)

これは非常に非効率的であるように思われ、開発者はファイルのローカルコピーを自分のマシンに保持する必要があるため、ソースコード管理の本質をほとんどバイパスします。これにより、ローカルファイルを誤ってチェックインしたり、ローカルファイルを上書きしたりする可能性もあります。

(ADFS)マシン固有の構成のコードをチェックインする方法についてのリファレンス、ドキュメント、または情報があり、開発環境全体を無駄にすることはありませんか?

前もって感謝します、

4

1 に答える 1

6

WIFツールセットが構成を行う方法は、複数の開発者やテスト環境を持つチームでの作業には適していないことに同意します。これを乗り越えるために私が取ったアプローチは、実行時に構成されるようにWIFを変更することです。

実行できるアプローチの1つは、ダミー/FederationMetadata/2007-06/FederationMetadata.xmlを配置してTFSにチェックインすることです。有効なURLが必要であり、それ以外の場合は有効なファイルである必要があります。

さらに、ダミー(ただし有効な形式)とエントリfederationAuthenticationを含むweb.configの有効なセクションが必要audienceUrisになります。issuerrealm

  <microsoft.identityModel>
    <service>
      <audienceUris>
        <add value="https://yourwebsite.com/" />
      </audienceUris>
      <federatedAuthentication>
        <wsFederation passiveRedirectEnabled="true" issuer="https://yourissuer/v2/wsfederation" realm="https://yourwebsite.com/" requireHttps="true" />
        <cookieHandler requireSsl="false" />
      </federatedAuthentication>
      etc...

次に、アプリケーションのADFS構成を完全にランタイム駆動型に変更します。これを行うには、ADFSモジュールの起動およびASP.NETパイプライン中にさまざまなイベントをフックします。

詳細については、このフォーラムの投稿をご覧ください。

基本的に、global.asax.csにこのようなものが必要になります。これは、Windows Azure WebロールでServiceConfiguration.cscfg(Azureモデルのデプロイ/実行時に変更可能)から読み取るために使用したコードです。これは、web.configまたは選択した他の構成システム(データベースなど)から読み取るように簡単に適合させることができます。

    protected void Application_Start(object sender, EventArgs e)
    {
        FederatedAuthentication.ServiceConfigurationCreated += OnServiceConfigurationCreated;
    }

    protected void Application_AuthenticateRequest(object sender, EventArgs e)
    {
        /// Due to the way the ASP.Net pipeline works, the only way to change 
        /// configurations inside federatedAuthentication (which are configurations on the http modules)
        /// is to catch another event, which is raised everytime a request comes in.
        ConfigureWSFederation();
    }

    /// <summary>
    /// Dynamically load WIF configuration so that it can live in ServiceConfiguration.cscfg instead of Web.config
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="eventArgs"></param>
    void OnServiceConfigurationCreated(object sender, ServiceConfigurationCreatedEventArgs eventArgs)
    {
        try
        {
            ServiceConfiguration serviceConfiguration = eventArgs.ServiceConfiguration;

            if (!String.IsNullOrEmpty(RoleEnvironment.GetConfigurationSettingValue("FedAuthAudienceUri")))
            {
                serviceConfiguration.AudienceRestriction.AllowedAudienceUris.Add(new Uri(RoleEnvironment.GetConfigurationSettingValue("FedAuthAudienceUri")));
                Trace.TraceInformation("ServiceConfiguration: AllowedAudienceUris = {0}", serviceConfiguration.AudienceRestriction.AllowedAudienceUris[0]);
            }

            serviceConfiguration.CertificateValidationMode = X509CertificateValidationMode.None;
            Trace.TraceInformation("ServiceConfiguration: CertificateValidationMode = {0}", serviceConfiguration.CertificateValidationMode);

            // Now load the trusted issuers
            if (serviceConfiguration.IssuerNameRegistry is ConfigurationBasedIssuerNameRegistry)
            {
                ConfigurationBasedIssuerNameRegistry issuerNameRegistry = serviceConfiguration.IssuerNameRegistry as ConfigurationBasedIssuerNameRegistry;

                // Can have more than one. We don't.
                issuerNameRegistry.AddTrustedIssuer(RoleEnvironment.GetConfigurationSettingValue("FedAuthTrustedIssuerThumbprint"), RoleEnvironment.GetConfigurationSettingValue("FedAuthTrustedIssuerName"));
                Trace.TraceInformation("ServiceConfiguration: TrustedIssuer = {0} : {1}", RoleEnvironment.GetConfigurationSettingValue("FedAuthTrustedIssuerThumbprint"), RoleEnvironment.GetConfigurationSettingValue("FedAuthTrustedIssuerName"));
            }
            else
            {
                Trace.TraceInformation("Custom IssuerNameReistry type configured, ignoring internal settings");
            }

            // Configures WIF to use the RsaEncryptionCookieTransform if ServiceCertificateThumbprint is specified.
            // This is only necessary on Windows Azure because DPAPI is not available.
            ConfigureWifToUseRsaEncryption(serviceConfiguration);
        }
        catch (Exception exception)
        {
            Trace.TraceError("Unable to initialize the federated authentication configuration. {0}", exception.Message);
        }
    }

    /// <summary>
    /// Configures WIF to use the RsaEncryptionCookieTransform, DPAPI is not available on Windows Azure.
    /// </summary>
    /// <param name="requestContext"></param>
    private void ConfigureWifToUseRsaEncryption(ServiceConfiguration serviceConfiguration)
    {
        String svcCertThumbprint = RoleEnvironment.GetConfigurationSettingValue("FedAuthServiceCertificateThumbprint");

        if (!String.IsNullOrEmpty(svcCertThumbprint))
        {
            X509Store certificateStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);

            try
            {
                certificateStore.Open(OpenFlags.ReadOnly);
                // We have to pass false as last parameter to find self-signed certs.
                X509Certificate2Collection certs = certificateStore.Certificates.Find(X509FindType.FindByThumbprint, svcCertThumbprint, false /*validOnly*/);

                if (certs.Count != 0)
                {
                    serviceConfiguration.ServiceCertificate = certs[0];
                    // Use the service certificate to protect the cookies that are sent to the client.
                    List<CookieTransform> sessionTransforms =
                        new List<CookieTransform>(new CookieTransform[] { new DeflateCookieTransform(),
                                new RsaEncryptionCookieTransform(serviceConfiguration.ServiceCertificate)});

                    SessionSecurityTokenHandler sessionHandler = new SessionSecurityTokenHandler(sessionTransforms.AsReadOnly());

                    serviceConfiguration.SecurityTokenHandlers.AddOrReplace(sessionHandler);
                    Trace.TraceInformation("ConfigureWifToUseRsaEncryption: Using RsaEncryptionCookieTransform for cookieTransform");
                }
                else
                {
                    Trace.TraceError("Could not find service certificate in the My store on LocalMachine");
                }
            }
            finally
            {
                certificateStore.Close();
            }
        }
    }

    private static void ConfigureWSFederation()
    {
        // Load the federatedAuthentication settings
        WSFederationAuthenticationModule federatedModule = FederatedAuthentication.WSFederationAuthenticationModule as WSFederationAuthenticationModule;
        if (federatedModule != null)
        {
            federatedModule.PassiveRedirectEnabled = true;

            if (!String.IsNullOrEmpty(RoleEnvironment.GetConfigurationSettingValue("FedAuthWSFederationRequireHttps")))
            {
                federatedModule.RequireHttps = bool.Parse(RoleEnvironment.GetConfigurationSettingValue("FedAuthWSFederationRequireHttps"));
            }
            if (!String.IsNullOrEmpty(RoleEnvironment.GetConfigurationSettingValue("FedAuthWSFederationIssuer")))
            {
                federatedModule.Issuer = RoleEnvironment.GetConfigurationSettingValue("FedAuthWSFederationIssuer");
            }
            if (!String.IsNullOrEmpty(RoleEnvironment.GetConfigurationSettingValue("FedAuthWSFederationRealm")))
            {
                federatedModule.Realm = RoleEnvironment.GetConfigurationSettingValue("FedAuthWSFederationRealm");
            }

            CookieHandler cookieHandler = FederatedAuthentication.SessionAuthenticationModule.CookieHandler;
            cookieHandler.RequireSsl = false;
        }
        else
        {
            Trace.TraceError("Unable to configure the federated module. The modules weren't loaded.");
        }
    }
}

これにより、実行時に次の設定を構成できるようになります。

  <Setting name="FedAuthAudienceUri" value="-- update with audience url. e.g. https://yourwebsite/ --" />
  <Setting name="FedAuthWSFederationIssuer" value="-- update with WSFederation endpoint. e.g. https://yourissuer/v2/wsfederation--" />
  <Setting name="FedAuthWSFederationRealm" value="-- update with WSFederation realm. e.g. https://yourwebsite/" />
  <Setting name="FedAuthTrustedIssuerThumbprint" value="-- update with certificate thumbprint from ACS configuration. e.g. cb27dd190485afe0f62e470e4e3578de51d52bf4--" />
  <Setting name="FedAuthTrustedIssuerName" value="-- update with issuer name. e.g. https://yourissuer/--" />
  <Setting name="FedAuthServiceCertificateThumbprint" value="-- update with service certificate thumbprint. e.g. same as HTTPS thumbprint: FE95C43CD4C4F1FC6BC1CA4349C3FF60433648DB --" />
  <Setting name="FedAuthWSFederationRequireHttps" value="true" />
于 2012-01-01T10:15:58.877 に答える