Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WCF / System.ServiceModel.Activation / System / ServiceModel / Activation / HostedAspNetEnvironment.cs / 1407647 / HostedAspNetEnvironment.cs
//---------------------------------------------------------------------------- // Copyright (c) Microsoft Corporation. All rights reserved. //--------------------------------------------------------------------------- namespace System.ServiceModel.Activation { using System.Collections.Generic; using System.Configuration; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Net; using System.Runtime; using System.Runtime.CompilerServices; using System.Security; using System.Security.Authentication.ExtendedProtection; using System.Security.Permissions; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Description; using System.Threading; using System.Transactions; using System.Web; using System.Web.Compilation; using System.Web.Configuration; class HostedAspNetEnvironment : AspNetEnvironment { // used to cache SiteName|ApplicationVirtualPath static string cachedServiceReference; // used to cache if windows auth is being used NullableisWindowsAuthentication; HostedAspNetEnvironment() : base() { } public override bool AspNetCompatibilityEnabled { get { return ServiceHostingEnvironment.AspNetCompatibilityEnabled; } } public override string ConfigurationPath { get { if (ServiceHostingEnvironment.CurrentVirtualPath != null) { return ServiceHostingEnvironment.CurrentVirtualPath + "web.config"; } else { return base.ConfigurationPath; } } } public override bool IsConfigurationBased { get { return ServiceHostingEnvironment.IsConfigurationBased; } } public override string CurrentVirtualPath { get { return ServiceHostingEnvironment.CurrentVirtualPath; } } public override string XamlFileBaseLocation { get { return ServiceHostingEnvironment.XamlFileBaseLocation; } } public static void Enable() { AspNetEnvironment hostedEnvironment = new HostedAspNetEnvironment(); AspNetEnvironment.Current = hostedEnvironment; } public override void AddHostingBehavior(ServiceHostBase serviceHost, ServiceDescription description) { VirtualPathExtension virtualPathExtension = serviceHost.Extensions.Find (); if (virtualPathExtension != null) { description.Behaviors.Add(new HostedBindingBehavior(virtualPathExtension)); } } public override bool IsWebConfigAboveApplication(object configHostingContext) { WebContext context = configHostingContext as WebContext; if (context != null) { return context.ApplicationLevel == WebApplicationLevel.AboveApplication; } return false; // if we don't recognize the context we can't enforce the special web.config logic } public override void EnsureCompatibilityRequirements(ServiceDescription description) { AspNetCompatibilityRequirementsAttribute aspNetCompatibilityRequirements = description.Behaviors.Find (); if (aspNetCompatibilityRequirements == null) { aspNetCompatibilityRequirements = new AspNetCompatibilityRequirementsAttribute(); description.Behaviors.Add(aspNetCompatibilityRequirements); } } public override bool TryGetFullVirtualPath(out string virtualPath) { // subclass will use the virtual path from the compiled string virtualPath = ServiceHostingEnvironment.FullVirtualPath; return true; } public override string GetAnnotationFromHost(ServiceHostBase host) { //Format Website name\Application Virtual Path|\relative service virtual path|serviceName if (host != null && host.Extensions != null) { string serviceName = (host.Description != null) ? host.Description.Name : string.Empty; string application = ServiceHostingEnvironment.ApplicationVirtualPath; string servicePath = string.Empty; VirtualPathExtension extension = host.Extensions.Find (); if (extension != null && extension.VirtualPath != null) { servicePath = extension.VirtualPath.Replace("~", application + "|"); return string.Format(CultureInfo.InvariantCulture, "{0}{1}|{2}", ServiceHostingEnvironment.SiteName, servicePath, serviceName); } } if (string.IsNullOrEmpty(HostedAspNetEnvironment.cachedServiceReference)) { HostedAspNetEnvironment.cachedServiceReference = string.Format(CultureInfo.InvariantCulture, "{0}{1}", ServiceHostingEnvironment.SiteName, ServiceHostingEnvironment.ApplicationVirtualPath); } return HostedAspNetEnvironment.cachedServiceReference; } [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - can be called outside of user context.")] public override void EnsureAllReferencedAssemblyLoaded() { BuildManager.GetReferencedAssemblies(); } public override BaseUriWithWildcard GetBaseUri(string transportScheme, Uri listenUri) { BaseUriWithWildcard baseAddress = null; HostedTransportConfigurationBase hostedConfiguration = HostedTransportConfigurationManager.GetConfiguration(transportScheme) as HostedTransportConfigurationBase; if (hostedConfiguration != null) { baseAddress = hostedConfiguration.FindBaseAddress(listenUri); if (baseAddress == null) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.Hosting_TransportBindingNotFound(listenUri.ToString()))); } } return baseAddress; } public override void ValidateHttpSettings(string virtualPath, bool isMetadataListener, bool usingDefaultSpnList, ref AuthenticationSchemes supportedSchemes, ref ExtendedProtectionPolicy extendedProtectionPolicy, ref string realm) { // Verify the authentication settings AuthenticationSchemes hostedSupportedSchemes = HostedTransportConfigurationManager.MetabaseSettings.GetAuthenticationSchemes(virtualPath); if (supportedSchemes == AuthenticationSchemes.Anonymous) { if ((hostedSupportedSchemes & AuthenticationSchemes.Anonymous) == 0) { if (isMetadataListener) { // We apply IIS settings to the ChannelListener to fix mex endpoints. if ((hostedSupportedSchemes & AuthenticationSchemes.Negotiate) != AuthenticationSchemes.None) { supportedSchemes = AuthenticationSchemes.Negotiate; } else { supportedSchemes = hostedSupportedSchemes; } } } } if ((supportedSchemes & hostedSupportedSchemes) == 0) { if (AuthenticationSchemesHelper.IsWindowsAuth(supportedSchemes)) { throw FxTrace.Exception.AsError(new NotSupportedException(SR.Hosting_AuthSchemesRequireWindowsAuth)); } else { throw FxTrace.Exception.AsError(new NotSupportedException(SR.Hosting_AuthSchemesRequireOtherAuth(supportedSchemes.ToString()))); } } if (supportedSchemes != AuthenticationSchemes.Anonymous) { //Compare the ExtendedProtectionPolicy setttings to IIS ExtendedProtectionPolicy iisPolicy = HostedTransportConfigurationManager.MetabaseSettings.GetExtendedProtectionPolicy(virtualPath); if (iisPolicy == null) //OS doesn't support CBT { if (extendedProtectionPolicy.PolicyEnforcement == PolicyEnforcement.Always) { throw FxTrace.Exception.AsError(new NotSupportedException(SR.ExtendedProtectionNotSupported)); } } else { if (isMetadataListener && ChannelBindingUtility.IsDefaultPolicy(extendedProtectionPolicy)) { //push the IIS policy onto the metadataListener if and only if the default policy is //in force. policy for non metadata listeners will still have to match IIS policy. extendedProtectionPolicy = iisPolicy; } else { if (!ChannelBindingUtility.AreEqual(iisPolicy, extendedProtectionPolicy)) { string mismatchErrorMessage; if (iisPolicy.PolicyEnforcement != extendedProtectionPolicy.PolicyEnforcement) { mismatchErrorMessage = SR.ExtendedProtectionPolicyEnforcementMismatch(iisPolicy.PolicyEnforcement, extendedProtectionPolicy.PolicyEnforcement); } else if (iisPolicy.ProtectionScenario != extendedProtectionPolicy.ProtectionScenario) { mismatchErrorMessage = SR.ExtendedProtectionPolicyScenarioMismatch(iisPolicy.ProtectionScenario, extendedProtectionPolicy.ProtectionScenario); } else { Fx.Assert(iisPolicy.CustomChannelBinding != extendedProtectionPolicy.CustomChannelBinding, "new case in ChannelBindingUtility.AreEqual to account for"); mismatchErrorMessage = SR.ExtendedProtectionPolicyCustomChannelBindingMismatch; } if (mismatchErrorMessage != null) { throw FxTrace.Exception.AsError(new NotSupportedException(SR.Hosting_ExtendedProtectionPoliciesMustMatch(mismatchErrorMessage))); } } //when using the default SPN list we auto generate, we should make sure that the IIS policy is also the default... ServiceNameCollection listenerSpnList = usingDefaultSpnList ? null : extendedProtectionPolicy.CustomServiceNames; if (!ChannelBindingUtility.IsSubset(iisPolicy.CustomServiceNames, listenerSpnList)) { throw FxTrace.Exception.AsError(new NotSupportedException(SR.Hosting_ExtendedProtectionPoliciesMustMatch(SR.Hosting_ExtendedProtectionSPNListNotSubset))); } } } } // Do not set realm for Cassini. if (!ServiceHostingEnvironment.IsSimpleApplicationHost) { // Set the realm realm = HostedTransportConfigurationManager.MetabaseSettings.GetRealm(virtualPath); } } public override bool ValidateHttpsSettings(string virtualPath, ref Nullable requireClientCertificate) { bool useHostedClientCertificateMapping = false; // Do not validate settings for Cassini. Actually current implementation of Cassini does not support HTTPS. if (!ServiceHostingEnvironment.IsSimpleApplicationHost) { // Validate Ssl Settings HttpAccessSslFlags sslFlags = HostedTransportConfigurationManager.MetabaseSettings.GetAccessSslFlags(virtualPath); HttpAccessSslFlags channelListenerSslFlags = HttpAccessSslFlags.None; // Validating SSL flags. SslRequireCert means "require client certificate" in IIS terminology. bool mismatched = false; if ((sslFlags & HttpAccessSslFlags.SslRequireCert) != 0) { // Require SSL. if (requireClientCertificate.HasValue) { if (!requireClientCertificate.Value) { // IIS requires client cert but the binding does not. mismatched = true; } } else { // We apply IIS settings to the ChannelListener to fix mex endpoints. requireClientCertificate = true; } } else if (requireClientCertificate.GetValueOrDefault()) { // IIS does not require client cert but the binding does. channelListenerSslFlags |= HttpAccessSslFlags.SslRequireCert; mismatched = true; } if (!mismatched) { if ((sslFlags & HttpAccessSslFlags.SslMapCert) != 0) { useHostedClientCertificateMapping = true; } } if (mismatched) { throw FxTrace.Exception.AsError(new NotSupportedException(SR.Hosting_SslSettingsMisconfigured( channelListenerSslFlags.ToString(), sslFlags.ToString()))); } } return useHostedClientCertificateMapping; } public override void ProcessNotMatchedEndpointAddress(Uri uri, string endpointName) { if (!object.ReferenceEquals(uri.Scheme, Uri.UriSchemeHttp) && !object.ReferenceEquals(uri.Scheme, Uri.UriSchemeHttps)) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.Hosting_NonHTTPInCompatibilityMode(endpointName))); } } public override void ValidateCompatibilityRequirements(AspNetCompatibilityRequirementsMode compatibilityMode) { if (compatibilityMode == AspNetCompatibilityRequirementsMode.Allowed) { return; } else if (ServiceHostingEnvironment.AspNetCompatibilityEnabled && compatibilityMode == AspNetCompatibilityRequirementsMode.NotAllowed) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.Hosting_ServiceCompatibilityNotAllowed)); } else if (!ServiceHostingEnvironment.AspNetCompatibilityEnabled && compatibilityMode == AspNetCompatibilityRequirementsMode.Required) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.Hosting_ServiceCompatibilityRequire)); } } public override IAspNetMessageProperty GetHostingProperty(Message message) { return GetHostingProperty(message, false); } IAspNetMessageProperty GetHostingProperty(Message message, bool removeFromMessage) { IAspNetMessageProperty result = null; object property; if (message.Properties.TryGetValue(HostingMessageProperty.Name, out property)) { result = (HostingMessageProperty)property; if (removeFromMessage) { message.Properties.Remove(HostingMessageProperty.Name); } } return result; } public override IAspNetMessageProperty PrepareMessageForDispatch(Message message) { ReceiveContext context = null; if (ReceiveContext.TryGet(message, out context) && !(context is ReceiveContextBusyCountWrapper)) { ReceiveContextBusyCountWrapper wrapper = new ReceiveContextBusyCountWrapper(context); message.Properties.Remove(ReceiveContext.Name); message.Properties.Add(ReceiveContext.Name, wrapper); } return GetHostingProperty(message, true); } public override void ApplyHostedContext(TransportChannelListener listener, BindingContext context) { VirtualPathExtension virtualPathExtension = context.BindingParameters.Find (); if (virtualPathExtension != null) { HostedMetadataBindingParameter metadataBindingParameter = context.BindingParameters.Find (); listener.ApplyHostedContext(virtualPathExtension.VirtualPath, metadataBindingParameter != null); } } public override void ProcessBehaviorForMetadataExtension(IServiceBehavior serviceBehavior, BindingParameterCollection bindingParameters) { if (serviceBehavior is HostedBindingBehavior) { bindingParameters.Add(((HostedBindingBehavior)serviceBehavior).VirtualPathExtension); bindingParameters.Add(new HostedMetadataBindingParameter()); } } public override void IncrementBusyCount() { HostingEnvironmentWrapper.IncrementBusyCount(); } public override void DecrementBusyCount() { HostingEnvironmentWrapper.DecrementBusyCount(); } public override bool TraceIncrementBusyCountIsEnabled() { return TD.IncrementBusyCountIsEnabled(); } public override bool TraceDecrementBusyCountIsEnabled() { return TD.DecrementBusyCountIsEnabled(); } public override void TraceIncrementBusyCount(string data) { if (data == null) { data = SR.DefaultBusyCountSource; } TD.IncrementBusyCount(data); } public override void TraceDecrementBusyCount(string data) { if (data == null) { data = SR.DefaultBusyCountSource; } TD.DecrementBusyCount(data); } public override object GetConfigurationSection(string sectionPath) { return GetSectionFromWebConfigurationManager(sectionPath, ServiceHostingEnvironment.FullVirtualPath); } [Fx.Tag.SecurityNote(Critical = "Uses SecurityCritical method UnsafeGetSectionFromWebConfigurationManager which elevates.")] [SecurityCritical] public override object UnsafeGetConfigurationSection(string sectionPath) { return UnsafeGetSectionFromWebConfigurationManager(sectionPath, ServiceHostingEnvironment.FullVirtualPath); } public override AuthenticationSchemes GetAuthenticationSchemes(Uri baseAddress) { string fileName = VirtualPathUtility.GetFileName(baseAddress.AbsolutePath); string virtualPath = ServiceHostingEnvironment.CurrentVirtualPath; string completePath; if (virtualPath != null && virtualPath.EndsWith("/", StringComparison.Ordinal)) { completePath = virtualPath + fileName; } else { completePath = string.Format(CultureInfo.InvariantCulture, "{0}/{1}", virtualPath, fileName); } AuthenticationSchemes supportedSchemes = HostedTransportConfigurationManager.MetabaseSettings.GetAuthenticationSchemes(completePath); if (ServiceHostingEnvironment.IsSimpleApplicationHost) { // Cassini always reports the auth scheme as anonymous or Ntlm. Map this to Ntlm, except when forms auth // is requested if (supportedSchemes == (AuthenticationSchemes.Anonymous | AuthenticationSchemes.Ntlm)) { if (IsWindowsAuthenticationConfigured()) { supportedSchemes = AuthenticationSchemes.Ntlm; } else { supportedSchemes = AuthenticationSchemes.Anonymous; } } } return supportedSchemes; } [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.", Safe = "Doesn't leak config objects out of SecurityCritical code.")] [SecuritySafeCritical] [MethodImpl(MethodImplOptions.NoInlining)] bool IsWindowsAuthenticationConfigured() { if (!this.isWindowsAuthentication.HasValue) { AuthenticationSection authSection = (AuthenticationSection)UnsafeGetConfigurationSection("system.web/authentication"); if (authSection != null) { this.isWindowsAuthentication = (authSection.Mode == AuthenticationMode.Windows); } else { this.isWindowsAuthentication = false; } } return this.isWindowsAuthentication.Value; } /// Be sure to update UnsafeGetSectionFromWebConfigurationManager if you modify this method [MethodImpl(MethodImplOptions.NoInlining)] static object GetSectionFromWebConfigurationManager(string sectionPath, string virtualPath) { if (virtualPath != null) { return WebConfigurationManager.GetSection(sectionPath, virtualPath); } else { return WebConfigurationManager.GetSection(sectionPath); } } // Be sure to update GetSectionFromWebConfigurationManager if you modify this method [SuppressMessage(FxCop.Category.Security, FxCop.Rule.SecureAsserts, Justification = "This is from an internal helper class and users have no way to pass arbitrary information to this code.")] [Fx.Tag.SecurityNote(Critical = "Asserts ConfigurationPermission in order to fetch config from WebConfigurationManager," + "caller must guard return value.")] [SecurityCritical] [ConfigurationPermission(SecurityAction.Assert, Unrestricted = true)] [MethodImpl(MethodImplOptions.NoInlining)] internal static object UnsafeGetSectionFromWebConfigurationManager(string sectionPath, string virtualPath) { if (virtualPath != null) { return WebConfigurationManager.GetSection(sectionPath, virtualPath); } else { return WebConfigurationManager.GetSection(sectionPath); } } // This class is intended to be empty. class HostedMetadataBindingParameter { } class ReceiveContextBusyCountWrapper : ReceiveContext { ReceiveContext wrappedContext; //possible values are 0 and 1. //using an integer to allow usage with Interlocked methods //synchronized access needed as there could be ---- between calls //to EndComplete and Tx notification. int busyCount; //possible values are 0 and 1 //using an integer to allow usage with Interlocked methods //synchronized access needed as there could be ---- between calls //to EndComplete and Tx Status notification. int ambientTransactionCount; internal ReceiveContextBusyCountWrapper(ReceiveContext context) { this.wrappedContext = context; this.wrappedContext.Faulted += new EventHandler(OnWrappedContextFaulted); AspNetEnvironment.Current.IncrementBusyCount(); if (AspNetEnvironment.Current.TraceIncrementBusyCountIsEnabled()) { AspNetEnvironment.Current.TraceIncrementBusyCount(this.GetType().FullName); } Interlocked.Increment(ref busyCount); } protected override void OnAbandon(TimeSpan timeout) { this.wrappedContext.Abandon(timeout); DecrementBusyCount(); } protected override IAsyncResult OnBeginAbandon(TimeSpan timeout, AsyncCallback callback, object state) { return this.wrappedContext.BeginAbandon(timeout, callback, state); } protected override IAsyncResult OnBeginComplete(TimeSpan timeout, AsyncCallback callback, object state) { RegisterForTransactionNotification(Transaction.Current); return this.wrappedContext.BeginComplete(timeout, callback, state); } protected override void OnComplete(TimeSpan timeout) { RegisterForTransactionNotification(Transaction.Current); this.wrappedContext.Complete(timeout); DecrementOnNoAmbientTransaction(); } protected override void OnEndAbandon(IAsyncResult result) { this.wrappedContext.EndAbandon(result); DecrementBusyCount(); } protected override void OnEndComplete(IAsyncResult result) { this.wrappedContext.EndComplete(result); DecrementOnNoAmbientTransaction(); } protected override void OnFaulted() { try { this.wrappedContext.Fault(); } finally { base.OnFaulted(); } } void OnWrappedContextFaulted(object sender, EventArgs e) { try { Fault(); } finally { DecrementBusyCount(); } } void RegisterForTransactionNotification(Transaction transaction) { if (Transaction.Current != null) { ReceiveContextEnlistmentNotification notification = new ReceiveContextEnlistmentNotification(this); transaction.EnlistVolatile(notification, EnlistmentOptions.None); Interlocked.Increment(ref this.ambientTransactionCount); } } void DecrementOnNoAmbientTransaction() { if (Interlocked.Exchange(ref this.ambientTransactionCount, 0) != 1) { DecrementBusyCount(); } } void DecrementBusyCount() { if (Interlocked.Exchange(ref this.busyCount, 0) == 1) { AspNetEnvironment.Current.DecrementBusyCount(); if (AspNetEnvironment.Current.TraceDecrementBusyCountIsEnabled()) { AspNetEnvironment.Current.TraceDecrementBusyCount(this.GetType().FullName); } } } class ReceiveContextEnlistmentNotification : IEnlistmentNotification { ReceiveContextBusyCountWrapper context; internal ReceiveContextEnlistmentNotification(ReceiveContextBusyCountWrapper context) { this.context = context; } public void Commit(Enlistment enlistment) { this.context.DecrementBusyCount(); enlistment.Done(); } public void InDoubt(Enlistment enlistment) { this.context.DecrementBusyCount(); enlistment.Done(); } public void Prepare(PreparingEnlistment preparingEnlistment) { preparingEnlistment.Prepared(); } public void Rollback(Enlistment enlistment) { enlistment.Done(); } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------------- // Copyright (c) Microsoft Corporation. All rights reserved. //--------------------------------------------------------------------------- namespace System.ServiceModel.Activation { using System.Collections.Generic; using System.Configuration; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Net; using System.Runtime; using System.Runtime.CompilerServices; using System.Security; using System.Security.Authentication.ExtendedProtection; using System.Security.Permissions; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Description; using System.Threading; using System.Transactions; using System.Web; using System.Web.Compilation; using System.Web.Configuration; class HostedAspNetEnvironment : AspNetEnvironment { // used to cache SiteName|ApplicationVirtualPath static string cachedServiceReference; // used to cache if windows auth is being used Nullable isWindowsAuthentication; HostedAspNetEnvironment() : base() { } public override bool AspNetCompatibilityEnabled { get { return ServiceHostingEnvironment.AspNetCompatibilityEnabled; } } public override string ConfigurationPath { get { if (ServiceHostingEnvironment.CurrentVirtualPath != null) { return ServiceHostingEnvironment.CurrentVirtualPath + "web.config"; } else { return base.ConfigurationPath; } } } public override bool IsConfigurationBased { get { return ServiceHostingEnvironment.IsConfigurationBased; } } public override string CurrentVirtualPath { get { return ServiceHostingEnvironment.CurrentVirtualPath; } } public override string XamlFileBaseLocation { get { return ServiceHostingEnvironment.XamlFileBaseLocation; } } public static void Enable() { AspNetEnvironment hostedEnvironment = new HostedAspNetEnvironment(); AspNetEnvironment.Current = hostedEnvironment; } public override void AddHostingBehavior(ServiceHostBase serviceHost, ServiceDescription description) { VirtualPathExtension virtualPathExtension = serviceHost.Extensions.Find (); if (virtualPathExtension != null) { description.Behaviors.Add(new HostedBindingBehavior(virtualPathExtension)); } } public override bool IsWebConfigAboveApplication(object configHostingContext) { WebContext context = configHostingContext as WebContext; if (context != null) { return context.ApplicationLevel == WebApplicationLevel.AboveApplication; } return false; // if we don't recognize the context we can't enforce the special web.config logic } public override void EnsureCompatibilityRequirements(ServiceDescription description) { AspNetCompatibilityRequirementsAttribute aspNetCompatibilityRequirements = description.Behaviors.Find (); if (aspNetCompatibilityRequirements == null) { aspNetCompatibilityRequirements = new AspNetCompatibilityRequirementsAttribute(); description.Behaviors.Add(aspNetCompatibilityRequirements); } } public override bool TryGetFullVirtualPath(out string virtualPath) { // subclass will use the virtual path from the compiled string virtualPath = ServiceHostingEnvironment.FullVirtualPath; return true; } public override string GetAnnotationFromHost(ServiceHostBase host) { //Format Website name\Application Virtual Path|\relative service virtual path|serviceName if (host != null && host.Extensions != null) { string serviceName = (host.Description != null) ? host.Description.Name : string.Empty; string application = ServiceHostingEnvironment.ApplicationVirtualPath; string servicePath = string.Empty; VirtualPathExtension extension = host.Extensions.Find (); if (extension != null && extension.VirtualPath != null) { servicePath = extension.VirtualPath.Replace("~", application + "|"); return string.Format(CultureInfo.InvariantCulture, "{0}{1}|{2}", ServiceHostingEnvironment.SiteName, servicePath, serviceName); } } if (string.IsNullOrEmpty(HostedAspNetEnvironment.cachedServiceReference)) { HostedAspNetEnvironment.cachedServiceReference = string.Format(CultureInfo.InvariantCulture, "{0}{1}", ServiceHostingEnvironment.SiteName, ServiceHostingEnvironment.ApplicationVirtualPath); } return HostedAspNetEnvironment.cachedServiceReference; } [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - can be called outside of user context.")] public override void EnsureAllReferencedAssemblyLoaded() { BuildManager.GetReferencedAssemblies(); } public override BaseUriWithWildcard GetBaseUri(string transportScheme, Uri listenUri) { BaseUriWithWildcard baseAddress = null; HostedTransportConfigurationBase hostedConfiguration = HostedTransportConfigurationManager.GetConfiguration(transportScheme) as HostedTransportConfigurationBase; if (hostedConfiguration != null) { baseAddress = hostedConfiguration.FindBaseAddress(listenUri); if (baseAddress == null) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.Hosting_TransportBindingNotFound(listenUri.ToString()))); } } return baseAddress; } public override void ValidateHttpSettings(string virtualPath, bool isMetadataListener, bool usingDefaultSpnList, ref AuthenticationSchemes supportedSchemes, ref ExtendedProtectionPolicy extendedProtectionPolicy, ref string realm) { // Verify the authentication settings AuthenticationSchemes hostedSupportedSchemes = HostedTransportConfigurationManager.MetabaseSettings.GetAuthenticationSchemes(virtualPath); if (supportedSchemes == AuthenticationSchemes.Anonymous) { if ((hostedSupportedSchemes & AuthenticationSchemes.Anonymous) == 0) { if (isMetadataListener) { // We apply IIS settings to the ChannelListener to fix mex endpoints. if ((hostedSupportedSchemes & AuthenticationSchemes.Negotiate) != AuthenticationSchemes.None) { supportedSchemes = AuthenticationSchemes.Negotiate; } else { supportedSchemes = hostedSupportedSchemes; } } } } if ((supportedSchemes & hostedSupportedSchemes) == 0) { if (AuthenticationSchemesHelper.IsWindowsAuth(supportedSchemes)) { throw FxTrace.Exception.AsError(new NotSupportedException(SR.Hosting_AuthSchemesRequireWindowsAuth)); } else { throw FxTrace.Exception.AsError(new NotSupportedException(SR.Hosting_AuthSchemesRequireOtherAuth(supportedSchemes.ToString()))); } } if (supportedSchemes != AuthenticationSchemes.Anonymous) { //Compare the ExtendedProtectionPolicy setttings to IIS ExtendedProtectionPolicy iisPolicy = HostedTransportConfigurationManager.MetabaseSettings.GetExtendedProtectionPolicy(virtualPath); if (iisPolicy == null) //OS doesn't support CBT { if (extendedProtectionPolicy.PolicyEnforcement == PolicyEnforcement.Always) { throw FxTrace.Exception.AsError(new NotSupportedException(SR.ExtendedProtectionNotSupported)); } } else { if (isMetadataListener && ChannelBindingUtility.IsDefaultPolicy(extendedProtectionPolicy)) { //push the IIS policy onto the metadataListener if and only if the default policy is //in force. policy for non metadata listeners will still have to match IIS policy. extendedProtectionPolicy = iisPolicy; } else { if (!ChannelBindingUtility.AreEqual(iisPolicy, extendedProtectionPolicy)) { string mismatchErrorMessage; if (iisPolicy.PolicyEnforcement != extendedProtectionPolicy.PolicyEnforcement) { mismatchErrorMessage = SR.ExtendedProtectionPolicyEnforcementMismatch(iisPolicy.PolicyEnforcement, extendedProtectionPolicy.PolicyEnforcement); } else if (iisPolicy.ProtectionScenario != extendedProtectionPolicy.ProtectionScenario) { mismatchErrorMessage = SR.ExtendedProtectionPolicyScenarioMismatch(iisPolicy.ProtectionScenario, extendedProtectionPolicy.ProtectionScenario); } else { Fx.Assert(iisPolicy.CustomChannelBinding != extendedProtectionPolicy.CustomChannelBinding, "new case in ChannelBindingUtility.AreEqual to account for"); mismatchErrorMessage = SR.ExtendedProtectionPolicyCustomChannelBindingMismatch; } if (mismatchErrorMessage != null) { throw FxTrace.Exception.AsError(new NotSupportedException(SR.Hosting_ExtendedProtectionPoliciesMustMatch(mismatchErrorMessage))); } } //when using the default SPN list we auto generate, we should make sure that the IIS policy is also the default... ServiceNameCollection listenerSpnList = usingDefaultSpnList ? null : extendedProtectionPolicy.CustomServiceNames; if (!ChannelBindingUtility.IsSubset(iisPolicy.CustomServiceNames, listenerSpnList)) { throw FxTrace.Exception.AsError(new NotSupportedException(SR.Hosting_ExtendedProtectionPoliciesMustMatch(SR.Hosting_ExtendedProtectionSPNListNotSubset))); } } } } // Do not set realm for Cassini. if (!ServiceHostingEnvironment.IsSimpleApplicationHost) { // Set the realm realm = HostedTransportConfigurationManager.MetabaseSettings.GetRealm(virtualPath); } } public override bool ValidateHttpsSettings(string virtualPath, ref Nullable requireClientCertificate) { bool useHostedClientCertificateMapping = false; // Do not validate settings for Cassini. Actually current implementation of Cassini does not support HTTPS. if (!ServiceHostingEnvironment.IsSimpleApplicationHost) { // Validate Ssl Settings HttpAccessSslFlags sslFlags = HostedTransportConfigurationManager.MetabaseSettings.GetAccessSslFlags(virtualPath); HttpAccessSslFlags channelListenerSslFlags = HttpAccessSslFlags.None; // Validating SSL flags. SslRequireCert means "require client certificate" in IIS terminology. bool mismatched = false; if ((sslFlags & HttpAccessSslFlags.SslRequireCert) != 0) { // Require SSL. if (requireClientCertificate.HasValue) { if (!requireClientCertificate.Value) { // IIS requires client cert but the binding does not. mismatched = true; } } else { // We apply IIS settings to the ChannelListener to fix mex endpoints. requireClientCertificate = true; } } else if (requireClientCertificate.GetValueOrDefault()) { // IIS does not require client cert but the binding does. channelListenerSslFlags |= HttpAccessSslFlags.SslRequireCert; mismatched = true; } if (!mismatched) { if ((sslFlags & HttpAccessSslFlags.SslMapCert) != 0) { useHostedClientCertificateMapping = true; } } if (mismatched) { throw FxTrace.Exception.AsError(new NotSupportedException(SR.Hosting_SslSettingsMisconfigured( channelListenerSslFlags.ToString(), sslFlags.ToString()))); } } return useHostedClientCertificateMapping; } public override void ProcessNotMatchedEndpointAddress(Uri uri, string endpointName) { if (!object.ReferenceEquals(uri.Scheme, Uri.UriSchemeHttp) && !object.ReferenceEquals(uri.Scheme, Uri.UriSchemeHttps)) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.Hosting_NonHTTPInCompatibilityMode(endpointName))); } } public override void ValidateCompatibilityRequirements(AspNetCompatibilityRequirementsMode compatibilityMode) { if (compatibilityMode == AspNetCompatibilityRequirementsMode.Allowed) { return; } else if (ServiceHostingEnvironment.AspNetCompatibilityEnabled && compatibilityMode == AspNetCompatibilityRequirementsMode.NotAllowed) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.Hosting_ServiceCompatibilityNotAllowed)); } else if (!ServiceHostingEnvironment.AspNetCompatibilityEnabled && compatibilityMode == AspNetCompatibilityRequirementsMode.Required) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.Hosting_ServiceCompatibilityRequire)); } } public override IAspNetMessageProperty GetHostingProperty(Message message) { return GetHostingProperty(message, false); } IAspNetMessageProperty GetHostingProperty(Message message, bool removeFromMessage) { IAspNetMessageProperty result = null; object property; if (message.Properties.TryGetValue(HostingMessageProperty.Name, out property)) { result = (HostingMessageProperty)property; if (removeFromMessage) { message.Properties.Remove(HostingMessageProperty.Name); } } return result; } public override IAspNetMessageProperty PrepareMessageForDispatch(Message message) { ReceiveContext context = null; if (ReceiveContext.TryGet(message, out context) && !(context is ReceiveContextBusyCountWrapper)) { ReceiveContextBusyCountWrapper wrapper = new ReceiveContextBusyCountWrapper(context); message.Properties.Remove(ReceiveContext.Name); message.Properties.Add(ReceiveContext.Name, wrapper); } return GetHostingProperty(message, true); } public override void ApplyHostedContext(TransportChannelListener listener, BindingContext context) { VirtualPathExtension virtualPathExtension = context.BindingParameters.Find (); if (virtualPathExtension != null) { HostedMetadataBindingParameter metadataBindingParameter = context.BindingParameters.Find (); listener.ApplyHostedContext(virtualPathExtension.VirtualPath, metadataBindingParameter != null); } } public override void ProcessBehaviorForMetadataExtension(IServiceBehavior serviceBehavior, BindingParameterCollection bindingParameters) { if (serviceBehavior is HostedBindingBehavior) { bindingParameters.Add(((HostedBindingBehavior)serviceBehavior).VirtualPathExtension); bindingParameters.Add(new HostedMetadataBindingParameter()); } } public override void IncrementBusyCount() { HostingEnvironmentWrapper.IncrementBusyCount(); } public override void DecrementBusyCount() { HostingEnvironmentWrapper.DecrementBusyCount(); } public override bool TraceIncrementBusyCountIsEnabled() { return TD.IncrementBusyCountIsEnabled(); } public override bool TraceDecrementBusyCountIsEnabled() { return TD.DecrementBusyCountIsEnabled(); } public override void TraceIncrementBusyCount(string data) { if (data == null) { data = SR.DefaultBusyCountSource; } TD.IncrementBusyCount(data); } public override void TraceDecrementBusyCount(string data) { if (data == null) { data = SR.DefaultBusyCountSource; } TD.DecrementBusyCount(data); } public override object GetConfigurationSection(string sectionPath) { return GetSectionFromWebConfigurationManager(sectionPath, ServiceHostingEnvironment.FullVirtualPath); } [Fx.Tag.SecurityNote(Critical = "Uses SecurityCritical method UnsafeGetSectionFromWebConfigurationManager which elevates.")] [SecurityCritical] public override object UnsafeGetConfigurationSection(string sectionPath) { return UnsafeGetSectionFromWebConfigurationManager(sectionPath, ServiceHostingEnvironment.FullVirtualPath); } public override AuthenticationSchemes GetAuthenticationSchemes(Uri baseAddress) { string fileName = VirtualPathUtility.GetFileName(baseAddress.AbsolutePath); string virtualPath = ServiceHostingEnvironment.CurrentVirtualPath; string completePath; if (virtualPath != null && virtualPath.EndsWith("/", StringComparison.Ordinal)) { completePath = virtualPath + fileName; } else { completePath = string.Format(CultureInfo.InvariantCulture, "{0}/{1}", virtualPath, fileName); } AuthenticationSchemes supportedSchemes = HostedTransportConfigurationManager.MetabaseSettings.GetAuthenticationSchemes(completePath); if (ServiceHostingEnvironment.IsSimpleApplicationHost) { // Cassini always reports the auth scheme as anonymous or Ntlm. Map this to Ntlm, except when forms auth // is requested if (supportedSchemes == (AuthenticationSchemes.Anonymous | AuthenticationSchemes.Ntlm)) { if (IsWindowsAuthenticationConfigured()) { supportedSchemes = AuthenticationSchemes.Ntlm; } else { supportedSchemes = AuthenticationSchemes.Anonymous; } } } return supportedSchemes; } [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.", Safe = "Doesn't leak config objects out of SecurityCritical code.")] [SecuritySafeCritical] [MethodImpl(MethodImplOptions.NoInlining)] bool IsWindowsAuthenticationConfigured() { if (!this.isWindowsAuthentication.HasValue) { AuthenticationSection authSection = (AuthenticationSection)UnsafeGetConfigurationSection("system.web/authentication"); if (authSection != null) { this.isWindowsAuthentication = (authSection.Mode == AuthenticationMode.Windows); } else { this.isWindowsAuthentication = false; } } return this.isWindowsAuthentication.Value; } /// Be sure to update UnsafeGetSectionFromWebConfigurationManager if you modify this method [MethodImpl(MethodImplOptions.NoInlining)] static object GetSectionFromWebConfigurationManager(string sectionPath, string virtualPath) { if (virtualPath != null) { return WebConfigurationManager.GetSection(sectionPath, virtualPath); } else { return WebConfigurationManager.GetSection(sectionPath); } } // Be sure to update GetSectionFromWebConfigurationManager if you modify this method [SuppressMessage(FxCop.Category.Security, FxCop.Rule.SecureAsserts, Justification = "This is from an internal helper class and users have no way to pass arbitrary information to this code.")] [Fx.Tag.SecurityNote(Critical = "Asserts ConfigurationPermission in order to fetch config from WebConfigurationManager," + "caller must guard return value.")] [SecurityCritical] [ConfigurationPermission(SecurityAction.Assert, Unrestricted = true)] [MethodImpl(MethodImplOptions.NoInlining)] internal static object UnsafeGetSectionFromWebConfigurationManager(string sectionPath, string virtualPath) { if (virtualPath != null) { return WebConfigurationManager.GetSection(sectionPath, virtualPath); } else { return WebConfigurationManager.GetSection(sectionPath); } } // This class is intended to be empty. class HostedMetadataBindingParameter { } class ReceiveContextBusyCountWrapper : ReceiveContext { ReceiveContext wrappedContext; //possible values are 0 and 1. //using an integer to allow usage with Interlocked methods //synchronized access needed as there could be ---- between calls //to EndComplete and Tx notification. int busyCount; //possible values are 0 and 1 //using an integer to allow usage with Interlocked methods //synchronized access needed as there could be ---- between calls //to EndComplete and Tx Status notification. int ambientTransactionCount; internal ReceiveContextBusyCountWrapper(ReceiveContext context) { this.wrappedContext = context; this.wrappedContext.Faulted += new EventHandler(OnWrappedContextFaulted); AspNetEnvironment.Current.IncrementBusyCount(); if (AspNetEnvironment.Current.TraceIncrementBusyCountIsEnabled()) { AspNetEnvironment.Current.TraceIncrementBusyCount(this.GetType().FullName); } Interlocked.Increment(ref busyCount); } protected override void OnAbandon(TimeSpan timeout) { this.wrappedContext.Abandon(timeout); DecrementBusyCount(); } protected override IAsyncResult OnBeginAbandon(TimeSpan timeout, AsyncCallback callback, object state) { return this.wrappedContext.BeginAbandon(timeout, callback, state); } protected override IAsyncResult OnBeginComplete(TimeSpan timeout, AsyncCallback callback, object state) { RegisterForTransactionNotification(Transaction.Current); return this.wrappedContext.BeginComplete(timeout, callback, state); } protected override void OnComplete(TimeSpan timeout) { RegisterForTransactionNotification(Transaction.Current); this.wrappedContext.Complete(timeout); DecrementOnNoAmbientTransaction(); } protected override void OnEndAbandon(IAsyncResult result) { this.wrappedContext.EndAbandon(result); DecrementBusyCount(); } protected override void OnEndComplete(IAsyncResult result) { this.wrappedContext.EndComplete(result); DecrementOnNoAmbientTransaction(); } protected override void OnFaulted() { try { this.wrappedContext.Fault(); } finally { base.OnFaulted(); } } void OnWrappedContextFaulted(object sender, EventArgs e) { try { Fault(); } finally { DecrementBusyCount(); } } void RegisterForTransactionNotification(Transaction transaction) { if (Transaction.Current != null) { ReceiveContextEnlistmentNotification notification = new ReceiveContextEnlistmentNotification(this); transaction.EnlistVolatile(notification, EnlistmentOptions.None); Interlocked.Increment(ref this.ambientTransactionCount); } } void DecrementOnNoAmbientTransaction() { if (Interlocked.Exchange(ref this.ambientTransactionCount, 0) != 1) { DecrementBusyCount(); } } void DecrementBusyCount() { if (Interlocked.Exchange(ref this.busyCount, 0) == 1) { AspNetEnvironment.Current.DecrementBusyCount(); if (AspNetEnvironment.Current.TraceDecrementBusyCountIsEnabled()) { AspNetEnvironment.Current.TraceDecrementBusyCount(this.GetType().FullName); } } } class ReceiveContextEnlistmentNotification : IEnlistmentNotification { ReceiveContextBusyCountWrapper context; internal ReceiveContextEnlistmentNotification(ReceiveContextBusyCountWrapper context) { this.context = context; } public void Commit(Enlistment enlistment) { this.context.DecrementBusyCount(); enlistment.Done(); } public void InDoubt(Enlistment enlistment) { this.context.DecrementBusyCount(); enlistment.Done(); } public void Prepare(PreparingEnlistment preparingEnlistment) { preparingEnlistment.Prepared(); } public void Rollback(Enlistment enlistment) { enlistment.Done(); } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- WindowShowOrOpenTracker.cs
- ArcSegment.cs
- ProtocolViolationException.cs
- DiscoveryEndpointValidator.cs
- TextBox.cs
- ResourcesGenerator.cs
- TextElementCollectionHelper.cs
- DbConnectionHelper.cs
- MenuItem.cs
- InstancePersistenceContext.cs
- DefaultPerformanceCounters.cs
- CommandID.cs
- ConfigsHelper.cs
- MultiBindingExpression.cs
- BaseValidatorDesigner.cs
- WriteableOnDemandPackagePart.cs
- DeploymentSection.cs
- InstanceNameConverter.cs
- ValidationError.cs
- AtomContentProperty.cs
- HandleRef.cs
- ObservableCollection.cs
- DrawTreeNodeEventArgs.cs
- Part.cs
- XmlCharCheckingReader.cs
- SqlCacheDependency.cs
- UniqueID.cs
- ProviderCommandInfoUtils.cs
- Int64Animation.cs
- ComboBoxRenderer.cs
- RuntimeEnvironment.cs
- XmlChoiceIdentifierAttribute.cs
- ShapeTypeface.cs
- X509CertificateClaimSet.cs
- XmlValidatingReader.cs
- JsonFaultDetail.cs
- MarkerProperties.cs
- AsyncInvokeOperation.cs
- Int16Storage.cs
- TypeUtil.cs
- ComplusTypeValidator.cs
- ItemContainerPattern.cs
- FlowLayoutSettings.cs
- UrlMappingsModule.cs
- PingOptions.cs
- Mouse.cs
- FocusWithinProperty.cs
- ProcessManager.cs
- VectorAnimationUsingKeyFrames.cs
- XmlSchemaGroupRef.cs
- FormsAuthentication.cs
- DSASignatureFormatter.cs
- MethodBuilder.cs
- ImageInfo.cs
- SymLanguageVendor.cs
- XamlPoint3DCollectionSerializer.cs
- BitmapEffectDrawing.cs
- SqlFunctionAttribute.cs
- InputEventArgs.cs
- Size3D.cs
- CommittableTransaction.cs
- ObjectItemConventionAssemblyLoader.cs
- SmtpTransport.cs
- MaskedTextProvider.cs
- BindingExpression.cs
- SmiRecordBuffer.cs
- ShaderEffect.cs
- uribuilder.cs
- ImageFormat.cs
- OleDbErrorCollection.cs
- XPathMultyIterator.cs
- SiteMapDataSourceView.cs
- MemberAccessException.cs
- SurrogateEncoder.cs
- WebPartVerbsEventArgs.cs
- SequentialUshortCollection.cs
- IdentifierCreationService.cs
- HttpMethodAttribute.cs
- EntityProviderFactory.cs
- Buffer.cs
- ValidationSummary.cs
- HttpContextBase.cs
- HtmlInputReset.cs
- BindingValueChangedEventArgs.cs
- Quad.cs
- ComplexTypeEmitter.cs
- Polygon.cs
- NodeInfo.cs
- TheQuery.cs
- HeaderCollection.cs
- ParagraphVisual.cs
- ToolStripDropDownClosedEventArgs.cs
- DataGridViewCellToolTipTextNeededEventArgs.cs
- DataServiceHost.cs
- MaskedTextBox.cs
- XmlCharCheckingReader.cs
- SqlBulkCopyColumnMapping.cs
- CallbackHandler.cs
- Helper.cs
- TraceSource.cs