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
- MsmqIntegrationInputMessage.cs
- XmlObjectSerializerReadContextComplex.cs
- PaperSize.cs
- TransformCollection.cs
- NeutralResourcesLanguageAttribute.cs
- FormsAuthenticationCredentials.cs
- InputLanguageEventArgs.cs
- WorkflowServiceOperationListItem.cs
- TextSelectionProcessor.cs
- WebPartUserCapability.cs
- GridViewPageEventArgs.cs
- SQLInt32.cs
- HScrollBar.cs
- SR.cs
- PageHandlerFactory.cs
- Quaternion.cs
- _SecureChannel.cs
- IndexedString.cs
- FormsAuthentication.cs
- OrderByBuilder.cs
- LogEntrySerialization.cs
- StreamWithDictionary.cs
- ActivityInterfaces.cs
- HScrollBar.cs
- Int16AnimationUsingKeyFrames.cs
- _HeaderInfoTable.cs
- BlobPersonalizationState.cs
- AmbiguousMatchException.cs
- FormsAuthenticationEventArgs.cs
- InputGestureCollection.cs
- Encoding.cs
- DataBindEngine.cs
- Preprocessor.cs
- Compiler.cs
- XmlHierarchicalDataSourceView.cs
- DbConnectionOptions.cs
- HashCryptoHandle.cs
- TriggerBase.cs
- ToolStripProgressBar.cs
- EncodingTable.cs
- MemoryPressure.cs
- FormCollection.cs
- DecimalConverter.cs
- SByte.cs
- GrammarBuilderRuleRef.cs
- SequenceFullException.cs
- ICspAsymmetricAlgorithm.cs
- PowerStatus.cs
- LineUtil.cs
- CorrelationManager.cs
- XmlChildEnumerator.cs
- GetWinFXPath.cs
- IUnknownConstantAttribute.cs
- SplitterEvent.cs
- AlternationConverter.cs
- StrongNameKeyPair.cs
- _RequestCacheProtocol.cs
- EventManager.cs
- ListViewDeleteEventArgs.cs
- Padding.cs
- DBAsyncResult.cs
- DropTarget.cs
- AssignDesigner.xaml.cs
- WebServiceMethodData.cs
- NestedContainer.cs
- isolationinterop.cs
- Label.cs
- SqlRecordBuffer.cs
- WebServiceFaultDesigner.cs
- SafeEventLogWriteHandle.cs
- WriteFileContext.cs
- DataGridItemAutomationPeer.cs
- ObjectIDGenerator.cs
- EventMappingSettingsCollection.cs
- HttpMethodAttribute.cs
- TreeNodeMouseHoverEvent.cs
- SchemaTypeEmitter.cs
- MeasurementDCInfo.cs
- ProjectionPruner.cs
- ISAPIRuntime.cs
- COM2FontConverter.cs
- RoleManagerSection.cs
- Rotation3DAnimationBase.cs
- ModelTreeManager.cs
- MLangCodePageEncoding.cs
- CoreSwitches.cs
- securestring.cs
- SecurityToken.cs
- SessionSwitchEventArgs.cs
- ExpressionStringBuilder.cs
- HttpConfigurationContext.cs
- SecurityState.cs
- OleDbTransaction.cs
- TTSEngineTypes.cs
- Parser.cs
- String.cs
- FunctionCommandText.cs
- ValueUnavailableException.cs
- CellLabel.cs
- HttpHandlersSection.cs