Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / HttpsChannelListener.cs / 1 / HttpsChannelListener.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.ServiceModel.Channels { using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.Net; using System.IdentityModel.Claims; using System.IdentityModel.Policy; using System.IdentityModel.Selectors; using System.IdentityModel.Tokens; using System.Security.Cryptography.X509Certificates; using System.Security.Principal; using System.Runtime.Serialization; using System.ServiceModel; using System.ServiceModel.Activation; using System.ServiceModel.Description; using System.ServiceModel.Diagnostics; using System.ServiceModel.Security; using System.ServiceModel.Security.Tokens; using System.Text; using System.Threading; using System.Web; class HttpsChannelListener : HttpChannelListener { bool useHostedClientCertificateMapping; bool requireClientCertificate; SecurityTokenAuthenticator certificateAuthenticator; const HttpStatusCode CertificateErrorStatusCode = HttpStatusCode.Forbidden; public HttpsChannelListener(HttpsTransportBindingElement httpsBindingElement, BindingContext context) : base(httpsBindingElement, context) { this.requireClientCertificate = httpsBindingElement.RequireClientCertificate; // Pick up the MapCertificateToWindowsAccuont setting from the configured token authenticator. SecurityCredentialsManager credentialProvider = context.BindingParameters.Find(); if (credentialProvider == null) { credentialProvider = ServiceCredentials.CreateDefaultCredentials(); } SecurityTokenManager tokenManager = credentialProvider.CreateSecurityTokenManager(); X509SecurityTokenAuthenticator authenticator = TransportSecurityHelpers.GetCertificateTokenAuthenticator(tokenManager, context.Binding.Scheme) as X509SecurityTokenAuthenticator; if (authenticator != null) { this.certificateAuthenticator = new X509SecurityTokenAuthenticator(X509CertificateValidator.None, authenticator.MapCertificateToWindowsAccount, this.ExtractGroupsForWindowsAccounts, false); } if (this.RequireClientCertificate && (this.AuthenticationScheme != AuthenticationSchemes.Anonymous)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelper(new InvalidOperationException(SR.GetString( SR.HttpAuthSchemeAndClientCert, this.AuthenticationScheme)), TraceEventType.Error); } } public bool RequireClientCertificate { get { return this.requireClientCertificate; } } public override string Scheme { get { return Uri.UriSchemeHttps; } } internal override UriPrefixTable TransportManagerTable { get { return SharedHttpsTransportManager.StaticTransportManagerTable; } } internal override void ApplyHostedContext(VirtualPathExtension virtualPathExtension, bool isMetadataListener) { base.ApplyHostedContext(virtualPathExtension, isMetadataListener); // 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(virtualPathExtension.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 (isMetadataListener) { // We apply IIS settings to the ChannelListener to fix mex endpoints. this.requireClientCertificate = true; } else if (!this.requireClientCertificate) { // IIS requires client cert but the binding does not. mismatched = true; } } else if (this.RequireClientCertificate) { // IIS does not require client cert but the binding does. channelListenerSslFlags |= HttpAccessSslFlags.SslRequireCert; mismatched = true; } if (!mismatched) { if ((sslFlags & HttpAccessSslFlags.SslMapCert) != 0) { this.useHostedClientCertificateMapping = true; } } if (mismatched) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.Hosting_SslSettingsMisconfigured, channelListenerSslFlags.ToString(), sslFlags.ToString()))); } } } internal override ITransportManagerRegistration CreateTransportManagerRegistration(Uri listenUri) { return new SharedHttpsTransportManager(listenUri, this); } // Note: the returned SecurityMessageProperty has ownership of certificate and identity. SecurityMessageProperty CreateSecurityProperty(X509Certificate2 certificate, WindowsIdentity identity) { SecurityToken token; if (identity != null) { token = new X509WindowsSecurityToken(certificate, identity, false); } else { token = new X509SecurityToken(certificate, false); } ReadOnlyCollection policies = this.certificateAuthenticator.ValidateToken(token); SecurityMessageProperty result = new SecurityMessageProperty(); result.TransportToken = new SecurityTokenSpecification(token, policies); result.ServiceSecurityContext = new ServiceSecurityContext(policies); return result; } public override SecurityMessageProperty ProcessAuthentication(HostedHttpRequestAsyncResult result) { if (this.requireClientCertificate) { SecurityMessageProperty retValue; X509Certificate2 certificate = null; try { HttpClientCertificate certInfo = result.Application.Request.ClientCertificate; DiagnosticUtility.DebugAssert(certInfo.IsPresent, "HostedHttpRequestAsyncResult.ClientCertificate is not present"); DiagnosticUtility.DebugAssert(certInfo.IsValid, "HostedHttpRequestAsyncResult.ClientCertificate is not valid"); certificate = new X509Certificate2(certInfo.Certificate); WindowsIdentity identity = null; if (this.useHostedClientCertificateMapping) { identity = result.LogonUserIdentity; if (identity == null || !identity.IsAuthenticated) { identity = WindowsIdentity.GetAnonymous(); } else { identity = SecurityUtils.CloneWindowsIdentityIfNecessary(identity); } } retValue = CreateSecurityProperty(certificate, identity); } #pragma warning suppress 56500 // covered by FXCop catch (Exception exception) { if (DiagnosticUtility.IsFatal(exception)) throw; // Audit Authentication failure if (AuditLevel.Failure == (this.AuditBehavior.MessageAuthenticationAuditLevel & AuditLevel.Failure)) WriteAuditEvent(AuditLevel.Failure, (certificate != null) ? SecurityUtils.GetCertificateId(certificate) : String.Empty, exception); throw; } // Audit Authentication success if (AuditLevel.Success == (this.AuditBehavior.MessageAuthenticationAuditLevel & AuditLevel.Success)) WriteAuditEvent(AuditLevel.Success, (certificate != null) ? SecurityUtils.GetCertificateId(certificate) : String.Empty, null); return retValue; } else if (this.AuthenticationScheme == AuthenticationSchemes.Anonymous) { return new SecurityMessageProperty(); } else { return base.ProcessAuthentication(result); } } public override SecurityMessageProperty ProcessAuthentication(HttpListenerContext listenerContext) { if (this.requireClientCertificate) { SecurityMessageProperty retValue; X509Certificate2 certificateEx = null; try { X509Certificate certificate = listenerContext.Request.GetClientCertificate(); DiagnosticUtility.DebugAssert(certificate != null, "HttpListenerRequest.ClientCertificate is not present"); DiagnosticUtility.DebugAssert(listenerContext.Request.ClientCertificateError == 0, "HttpListenerRequest.ClientCertificate is not valid"); certificateEx = new X509Certificate2(certificate.Handle); retValue = CreateSecurityProperty(certificateEx, null); } #pragma warning suppress 56500 // covered by FXCop catch (Exception exception) { if (DiagnosticUtility.IsFatal(exception)) throw; // Audit Authentication failure if (AuditLevel.Failure == (this.AuditBehavior.MessageAuthenticationAuditLevel & AuditLevel.Failure)) WriteAuditEvent(AuditLevel.Failure, (certificateEx != null) ? SecurityUtils.GetCertificateId(certificateEx) : String.Empty, exception); throw; } // Audit Authentication success if (AuditLevel.Success == (this.AuditBehavior.MessageAuthenticationAuditLevel & AuditLevel.Success)) WriteAuditEvent(AuditLevel.Success, (certificateEx != null) ? SecurityUtils.GetCertificateId(certificateEx) : String.Empty, null); return retValue; } else if (this.AuthenticationScheme == AuthenticationSchemes.Anonymous) { return new SecurityMessageProperty(); } else { return base.ProcessAuthentication(listenerContext); } } public override HttpStatusCode ValidateAuthentication(HostedHttpRequestAsyncResult hostedAsyncResult) { HttpStatusCode result = base.ValidateAuthentication(hostedAsyncResult); HttpRequest request = hostedAsyncResult.Application.Request; if (result == HttpStatusCode.OK) { if (this.RequireClientCertificate) { HttpClientCertificate certificate = request.ClientCertificate; if (!certificate.IsPresent) { if (DiagnosticUtility.ShouldTraceError) { TraceUtility.TraceEvent(TraceEventType.Error, TraceCode.HttpsClientCertificateNotPresent, new HttpRequestTraceRecord(request), this, null); } result = CertificateErrorStatusCode; } else if (!certificate.IsValid) { if (DiagnosticUtility.ShouldTraceError) { TraceUtility.TraceEvent(TraceEventType.Error, TraceCode.HttpsClientCertificateInvalid, new HttpRequestTraceRecord(request), this, null); } result = CertificateErrorStatusCode; } // Audit Authentication failure if (result != HttpStatusCode.OK && (AuditLevel.Failure == (this.AuditBehavior.MessageAuthenticationAuditLevel & AuditLevel.Failure))) { string message = SR.GetString(SR.HttpAuthenticationFailed, this.AuthenticationScheme, result); X509Certificate2 certificateEx = (certificate.IsPresent) ? new X509Certificate2(certificate.Certificate) : null; Exception exception = DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(message)); WriteAuditEvent(AuditLevel.Failure, (certificateEx != null) ? SecurityUtils.GetCertificateId(certificateEx) : String.Empty, exception); } } } return result; } public override HttpStatusCode ValidateAuthentication(HttpListenerContext listenerContext) { HttpStatusCode result = base.ValidateAuthentication(listenerContext); if (result == HttpStatusCode.OK) { if (this.RequireClientCertificate) { HttpListenerRequest request = listenerContext.Request; X509Certificate2 certificateEx = request.GetClientCertificate(); if (certificateEx == null) { if (DiagnosticUtility.ShouldTraceWarning) { TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.HttpsClientCertificateNotPresent, new HttpListenerRequestTraceRecord(listenerContext.Request), this, null); } result = CertificateErrorStatusCode; } else if (request.ClientCertificateError != 0) { if (DiagnosticUtility.ShouldTraceWarning) { TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.HttpsClientCertificateInvalid, new HttpListenerRequestTraceRecord(listenerContext.Request), this, null); } result = CertificateErrorStatusCode; } // Audit Authentication failure if (result != HttpStatusCode.OK && (AuditLevel.Failure == (this.AuditBehavior.MessageAuthenticationAuditLevel & AuditLevel.Failure))) { string message = SR.GetString(SR.HttpAuthenticationFailed, this.AuthenticationScheme, result); Exception exception = DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(message)); WriteAuditEvent(AuditLevel.Failure, (certificateEx != null) ? SecurityUtils.GetCertificateId(certificateEx) : String.Empty, exception); } } } return result; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- BinaryWriter.cs
- XmlQualifiedNameTest.cs
- FormViewPagerRow.cs
- itemelement.cs
- DbProviderFactoriesConfigurationHandler.cs
- StructuralCache.cs
- SecurityRuntime.cs
- PreloadedPackages.cs
- DefinitionUpdate.cs
- UpdateExpressionVisitor.cs
- TrustDriver.cs
- VectorCollection.cs
- WindowsStatusBar.cs
- KeyTimeConverter.cs
- BoolExpressionVisitors.cs
- ListQueryResults.cs
- SQLGuid.cs
- SpinLock.cs
- PrintPreviewGraphics.cs
- StringOutput.cs
- FrameworkElementFactoryMarkupObject.cs
- EntityContainerEntitySetDefiningQuery.cs
- EdmValidator.cs
- EventLogWatcher.cs
- Privilege.cs
- _Connection.cs
- CommandID.cs
- PenThreadPool.cs
- RowParagraph.cs
- precedingsibling.cs
- DeflateStreamAsyncResult.cs
- ScrollChrome.cs
- NumericUpDownAcceleration.cs
- Funcletizer.cs
- RegistryKey.cs
- ReadOnlyTernaryTree.cs
- EventWaitHandle.cs
- CatalogZoneBase.cs
- ImagingCache.cs
- ThumbAutomationPeer.cs
- DesignSurfaceEvent.cs
- SerializationFieldInfo.cs
- VersionPair.cs
- ToolStripRenderEventArgs.cs
- CompilerWrapper.cs
- TraceUtility.cs
- DataControlFieldCollection.cs
- RegexCode.cs
- DiagnosticTraceSource.cs
- ConnectionPoolManager.cs
- DataObjectSettingDataEventArgs.cs
- TabControl.cs
- CoTaskMemSafeHandle.cs
- XsdCachingReader.cs
- Enlistment.cs
- RenderingEventArgs.cs
- BitmapEffectvisualstate.cs
- BCLDebug.cs
- ArgumentNullException.cs
- PrivilegedConfigurationManager.cs
- BindingNavigator.cs
- Package.cs
- QilPatternVisitor.cs
- ErrorRuntimeConfig.cs
- wmiprovider.cs
- SplineKeyFrames.cs
- TransformerConfigurationWizardBase.cs
- FactoryMaker.cs
- TypeDelegator.cs
- WinEventHandler.cs
- SerializationObjectManager.cs
- BitmapData.cs
- PaperSize.cs
- MouseButton.cs
- Vector3D.cs
- WindowsTab.cs
- SafeSecurityHelper.cs
- GlyphsSerializer.cs
- ExpressionVisitorHelpers.cs
- BindUriHelper.cs
- SvcMapFileSerializer.cs
- Query.cs
- ImageIndexConverter.cs
- MDIClient.cs
- QilValidationVisitor.cs
- grammarelement.cs
- MediaSystem.cs
- RectangleHotSpot.cs
- InputScopeManager.cs
- EndpointDispatcher.cs
- MatrixKeyFrameCollection.cs
- XmlIlVisitor.cs
- Soap.cs
- GenerateScriptTypeAttribute.cs
- SettingsBindableAttribute.cs
- UICuesEvent.cs
- DbConnectionPool.cs
- EventRoute.cs
- ParameterRetriever.cs
- SoapMessage.cs