我同意 WIF 工具集进行配置的方式不适合在具有多个开发人员和测试环境的团队中工作。我采取的解决方法是将 WIF 更改为在运行时进行配置。
您可以采取的一种方法是放置一个假人/FederationMetadata/2007-06/FederationMetadata.xml
并将其签入 TFS。它必须具有有效的 url,否则是有效的文件。
此外,您将需要federationAuthentication
web.config 中的有效部分,其中包含虚拟(但形式有效)audienceUris
和issuer
条目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" />