2

我正在开发一个 asp.net Web 应用程序,它是 TFS 的一部分并由开发团队使用。最近,作为项目的一部分,我们设置了 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 更改为在运行时进行配置。

您可以采取的一种方法是放置一个假人/FederationMetadata/2007-06/FederationMetadata.xml并将其签入 TFS。它必须具有有效的 url,否则是有效的文件。

此外,您将需要federationAuthenticationweb.config 中的有效部分,其中包含虚拟(但形式有效)audienceUrisissuer条目realm

  <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 回答