Code:
/ 4.0 / 4.0 / untmp / 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.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- OneOfTypeConst.cs
- DiagnosticTrace.cs
- SettingsProviderCollection.cs
- XmlSchemaComplexContent.cs
- TextRangeEditLists.cs
- InProcStateClientManager.cs
- EntitySetBase.cs
- WebConfigurationManager.cs
- Geometry.cs
- InputBinder.cs
- RenderingEventArgs.cs
- TypeConverterAttribute.cs
- QilXmlWriter.cs
- FontEmbeddingManager.cs
- StopStoryboard.cs
- FormatterConverter.cs
- SystemMulticastIPAddressInformation.cs
- CodeNamespaceCollection.cs
- CodeCatchClauseCollection.cs
- EmissiveMaterial.cs
- FileLoadException.cs
- PackageStore.cs
- LogReserveAndAppendState.cs
- StateChangeEvent.cs
- DesignTimeResourceProviderFactoryAttribute.cs
- DeferredTextReference.cs
- FrameworkContextData.cs
- DesignerVerb.cs
- DataGridViewColumnCollection.cs
- _DomainName.cs
- HeaderedContentControl.cs
- ConsumerConnectionPoint.cs
- HtmlTernaryTree.cs
- Expressions.cs
- TouchFrameEventArgs.cs
- InputReport.cs
- EventSourceCreationData.cs
- DeclarationUpdate.cs
- DynamicQueryableWrapper.cs
- ColorConverter.cs
- NestedContainer.cs
- ComponentDispatcherThread.cs
- ModelPerspective.cs
- EntityDataSourceWizardForm.cs
- ObjectStateFormatter.cs
- SchemaNamespaceManager.cs
- TrustManagerPromptUI.cs
- RoleServiceManager.cs
- Script.cs
- ContentType.cs
- SelectionProcessor.cs
- WebPartEditorCancelVerb.cs
- LoginUtil.cs
- ToolStripRenderEventArgs.cs
- Pair.cs
- XmlChildNodes.cs
- HuffCodec.cs
- util.cs
- MultiPageTextView.cs
- DataControlButton.cs
- ClientSponsor.cs
- BufferModesCollection.cs
- FixedNode.cs
- _AutoWebProxyScriptWrapper.cs
- GeneralTransform3DTo2D.cs
- QueueProcessor.cs
- DrawingAttributes.cs
- JoinCqlBlock.cs
- Line.cs
- ComponentRenameEvent.cs
- KeyGesture.cs
- LexicalChunk.cs
- Pair.cs
- ContentElement.cs
- TracedNativeMethods.cs
- InputBuffer.cs
- HttpStaticObjectsCollectionWrapper.cs
- DataSysAttribute.cs
- InitializerFacet.cs
- WindowsGraphics.cs
- KeyInfo.cs
- Base64Stream.cs
- HttpListenerRequest.cs
- SmtpNegotiateAuthenticationModule.cs
- OutputCacheProfileCollection.cs
- Tablet.cs
- MetaChildrenColumn.cs
- UriTemplateClientFormatter.cs
- DbConnectionPool.cs
- ReachIDocumentPaginatorSerializer.cs
- GridViewEditEventArgs.cs
- SqlDelegatedTransaction.cs
- PartManifestEntry.cs
- TypeResolver.cs
- SerialErrors.cs
- BitStack.cs
- ScrollViewer.cs
- FirstMatchCodeGroup.cs
- XmlSchemaAnyAttribute.cs
- ActivationWorker.cs