using System; using System.Web; using System.Web.Mvc; using System.Web.Optimization; using System.Web.Routing; using FDOT.Enterprise; namespace FDOT.Security.STS.RPExample { public class MvcApplication : HttpApplication { /// <summary> /// Identity Config based Application_Start /// </summary> protected void Application_Start() { var environmentLevel = LocalSettings.EnvironmentLevel; AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); if (environmentLevel == EnvironmentLevel.WorkstationOrUnknown) IdentityConfig.ConfigureIdentity(IdentityConfig.StsConfiguration.devToUnit); else if (environmentLevel == EnvironmentLevel.Production) IdentityConfig.ConfigureIdentity(IdentityConfig.StsConfiguration.prod); else if (environmentLevel == EnvironmentLevel.SystemTest) IdentityConfig.ConfigureIdentity(IdentityConfig.StsConfiguration.system); else if (environmentLevel == EnvironmentLevel.UnitTest) IdentityConfig.ConfigureIdentity(IdentityConfig.StsConfiguration.unit); } private void Application_BeginRequest(object sender, EventArgs e) { if (String.Compare(Request.Path, Request.ApplicationPath, StringComparison.InvariantCultureIgnoreCase) == 0 && !Request.Path.EndsWith("/")) { // This corrects WIF error ID3206 "A SignInResponse message may only redirect within the current web application: '/NHP' is not allowed." // For whatever reason, accessing the site without a trailing slash causes this error. if (!Request.Path.EndsWith("/")) { Response.Redirect(Request.Path + "/"); } } switch (Request.Url.Scheme) { case "https": Response.AddHeader("Strict-Transport-Security", "max-age=300"); break; case "http": var path = "https://" + Request.Url.Host + Request.Url.PathAndQuery; Response.Status = "301 Moved Permanently"; Response.AddHeader("Location", path); break; } } } }
using System; using System.Configuration; using System.IdentityModel.Configuration; using System.IdentityModel.Services; using System.IdentityModel.Services.Configuration; using System.IdentityModel.Tokens; using System.Linq; using System.Security.Cryptography.X509Certificates; using System.ServiceModel.Security; namespace FDOT.Security.STS.RPExample { public static class IdentityConfig { #region Public Properties public static string AudienceUri { get; set; } public static string Realm { get; set; } public static string Authority { get; set; } public static string Issuer { get; set; } public static string EncryptionThumb { get; set; } public static string SigningThumb { get; set; } public static string FederationMetadataLocation { get; set; } #endregion public enum StsConfiguration { system, unit, prod, devToUnit } #region Public Methods public static void ConfigureIdentity(StsConfiguration stsConfiguration) { ConfigureIdentity(stsConfiguration.ToString()); } public static void ConfigureIdentity(string configurationKeyPrefix) { if (!configurationKeyPrefix.EndsWith(":")) configurationKeyPrefix = string.Concat(configurationKeyPrefix, ":"); Realm = ConfigurationManager.AppSettings.Get(string.Concat(configurationKeyPrefix, "Realm")); AudienceUri = ConfigurationManager.AppSettings.Get(string.Concat(configurationKeyPrefix, "AudienceUri")); FederationMetadataLocation = ConfigurationManager.AppSettings.Get(string.Concat(configurationKeyPrefix, "FederationMetadataLocation")); Authority = ConfigurationManager.AppSettings.Get(string.Concat(configurationKeyPrefix, "Authority")); Issuer = ConfigurationManager.AppSettings.Get(string.Concat(configurationKeyPrefix, "Issuer")); SigningThumb = ConfigurationManager.AppSettings.Get(string.Concat(configurationKeyPrefix, "SigningThumb")); EncryptionThumb = ConfigurationManager.AppSettings.Get(string.Concat(configurationKeyPrefix, "EncryptionThumb")); if (configurationKeyPrefix != "ida:") { ConfigurationManager.AppSettings.Set("ida:Realm",Realm); ConfigurationManager.AppSettings.Set("ida:AudienceUri", AudienceUri); ConfigurationManager.AppSettings.Set("ida:Authority", Authority); ConfigurationManager.AppSettings.Set("ida:Issuer", Issuer); ConfigurationManager.AppSettings.Set("ida:FederationMetadataLocation", FederationMetadataLocation); ConfigurationManager.AppSettings.Set("ida:SigningThumb", SigningThumb); ConfigurationManager.AppSettings.Set("ida:EncryptionThumb", EncryptionThumb); } AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Name; FederatedAuthentication.FederationConfigurationCreated += FederatedAuthentication_FederationConfigurationCreated; } #endregion #region Event Handlers private static void FederatedAuthentication_FederationConfigurationCreated(object sender, FederationConfigurationCreatedEventArgs e) { FederatedAuthentication.FederationConfigurationCreated -= FederatedAuthentication_FederationConfigurationCreated; var federationConfiguration = new FederationConfiguration(); e.FederationConfiguration = Create(federationConfiguration); } #endregion #region Helpers public static FederationConfiguration Create(FederationConfiguration federationConfiguration) { var encryptionCertificate = FindCertificate(EncryptionThumb); if (encryptionCertificate == null && Realm != ConfigurationManager.AppSettings["devToUnit:Realm"]) { throw new ArgumentOutOfRangeException("EncryptionThumb", "Encryption Certificate is required"); } var issuingAuthority = BuildIssuingAuthority(); var issuerNameRegistry = BuildIssuerNameRegistry(issuingAuthority); var identityConfiguration = BuildIdentityConfiguration(issuerNameRegistry); var cookieHandler = BuildCookieHandler(); federationConfiguration.CookieHandler = cookieHandler; federationConfiguration.IdentityConfiguration = identityConfiguration; var authModesQs = string.Format("authModes={0}", ConfigurationManager.AppSettings.Get("authModes")); AddWsFederationConfiguration(federationConfiguration, authModesQs); ConfigureCertificates(federationConfiguration, encryptionCertificate); ConfigureSSL(federationConfiguration); federationConfiguration.IdentityConfiguration.SecurityTokenHandlers.AddOrReplace( new MachineKeySessionSecurityTokenHandler()); return federationConfiguration; } private static IssuingAuthority BuildIssuingAuthority() { IssuingAuthority issuingAuthority = new IssuingAuthority(Authority); issuingAuthority.Issuers.Add(Authority); issuingAuthority.Issuers.Add(Issuer); return issuingAuthority; } private static ValidatingIssuerNameRegistry BuildIssuerNameRegistry(IssuingAuthority issuingAuthority) { return new ValidatingIssuerNameRegistry(issuingAuthority); } private static void AddWsFederationConfiguration(FederationConfiguration federationConfiguration,string authModes) { var wsFederationConfiguration = new WsFederationConfiguration(Issuer,Realm) {SignInQueryString = authModes}; federationConfiguration.WsFederationConfiguration = wsFederationConfiguration; federationConfiguration.WsFederationConfiguration.PassiveRedirectEnabled = true; } private static IdentityConfiguration BuildIdentityConfiguration(ValidatingIssuerNameRegistry issuerNameRegistry) { IdentityConfiguration identityConfiguration = new IdentityConfiguration(); identityConfiguration.AudienceRestriction.AllowedAudienceUris.Add(new Uri(Realm)); identityConfiguration.IssuerNameRegistry = issuerNameRegistry; identityConfiguration.DetectReplayedTokens = true; return identityConfiguration; } private static CookieHandler BuildCookieHandler() { return new ChunkedCookieHandler(); } private static void ConfigureCertificates(FederationConfiguration federationConfiguration, X509Certificate2 encryptionCertificate) { if (Realm != ConfigurationManager.AppSettings["devToUnit:Realm"]) federationConfiguration.ServiceCertificate = encryptionCertificate; var validatingRegistry = federationConfiguration.IdentityConfiguration.IssuerNameRegistry as ValidatingIssuerNameRegistry; if (validatingRegistry != null && Realm != ConfigurationManager.AppSettings["devToUnit:Realm"]) { //not test validatingRegistry.IssuingAuthorities.First().Thumbprints.Add(SigningThumb); federationConfiguration.IdentityConfiguration.CertificateValidationMode = X509CertificateValidationMode.ChainTrust; federationConfiguration.IdentityConfiguration.ServiceCertificate = encryptionCertificate; } else if (validatingRegistry != null && Realm == ConfigurationManager.AppSettings["devToUnit:Realm"]) { //test validatingRegistry.IssuingAuthorities.First().Thumbprints.Add(SigningThumb); federationConfiguration.IdentityConfiguration.CertificateValidationMode = X509CertificateValidationMode.None; } } private static void ConfigureSSL(FederationConfiguration federationConfiguration) { federationConfiguration.CookieHandler.RequireSsl = true; federationConfiguration.WsFederationConfiguration.RequireHttps = true; } private static X509Certificate2 FindCertificate(string thumb) { X509Certificate2 cert = null; if (!string.IsNullOrEmpty(thumb)) { var store = new X509Store(StoreName.My, StoreLocation.LocalMachine); store.Open(OpenFlags.ReadOnly); try { var certificate = store.Certificates.Find(X509FindType.FindByThumbprint, thumb, true); if (certificate.Count > 0) { cert = certificate[0]; } } finally { store.Close(); } } return cert; } #endregion } }