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
- SqlBinder.cs
- RC2.cs
- DataTransferEventArgs.cs
- DbParameterCollectionHelper.cs
- PageThemeParser.cs
- SqlDataSourceTableQuery.cs
- DataTablePropertyDescriptor.cs
- SupportingTokenDuplexChannel.cs
- JoinTreeNode.cs
- ObjectViewQueryResultData.cs
- LogWriteRestartAreaState.cs
- GrammarBuilderPhrase.cs
- RegionInfo.cs
- LayoutEvent.cs
- PersonalizationProvider.cs
- ISCIIEncoding.cs
- MethodToken.cs
- NativeRecognizer.cs
- AnimatedTypeHelpers.cs
- SQLChars.cs
- ImageButton.cs
- IdentityHolder.cs
- FormViewCommandEventArgs.cs
- StylusCaptureWithinProperty.cs
- SamlNameIdentifierClaimResource.cs
- SelectionHighlightInfo.cs
- CompiledRegexRunnerFactory.cs
- DocumentPage.cs
- ProfessionalColors.cs
- DataGridTableCollection.cs
- CollectionViewSource.cs
- EmptyReadOnlyDictionaryInternal.cs
- Deserializer.cs
- CheckBoxStandardAdapter.cs
- MexNamedPipeBindingCollectionElement.cs
- TextEditorCharacters.cs
- AnnotationDocumentPaginator.cs
- CopyCodeAction.cs
- EntityContainerRelationshipSetEnd.cs
- WebScriptEndpoint.cs
- BitmapMetadataBlob.cs
- MenuCommandService.cs
- BitmapSourceSafeMILHandle.cs
- DispatcherExceptionEventArgs.cs
- ExtenderControl.cs
- ControlIdConverter.cs
- FontFamily.cs
- EastAsianLunisolarCalendar.cs
- BaseContextMenu.cs
- VarRemapper.cs
- DrawListViewSubItemEventArgs.cs
- TrimSurroundingWhitespaceAttribute.cs
- xdrvalidator.cs
- SamlAuthorizationDecisionClaimResource.cs
- PropertyGroupDescription.cs
- ToolboxItemAttribute.cs
- AddInActivator.cs
- ListViewInsertEventArgs.cs
- StatusBarAutomationPeer.cs
- followingquery.cs
- DescendentsWalkerBase.cs
- EntityViewGenerationAttribute.cs
- PowerStatus.cs
- EntityReference.cs
- SqlBuffer.cs
- EtwTrace.cs
- TrackingStringDictionary.cs
- GroupDescription.cs
- InternalConfigEventArgs.cs
- WebControl.cs
- GPPOINT.cs
- HeaderFilter.cs
- TypeDescriptionProvider.cs
- XmlSchemaSequence.cs
- StructuralComparisons.cs
- ExitEventArgs.cs
- FileSecurity.cs
- SplashScreen.cs
- HeaderCollection.cs
- BookmarkList.cs
- PageAdapter.cs
- RequiredAttributeAttribute.cs
- WinHttpWebProxyFinder.cs
- AssemblyResourceLoader.cs
- VBCodeProvider.cs
- DataFormats.cs
- WebPartsPersonalization.cs
- DrawingGroup.cs
- Types.cs
- baseaxisquery.cs
- MainMenu.cs
- PolyLineSegment.cs
- DocumentPageViewAutomationPeer.cs
- OdbcCommand.cs
- OracleLob.cs
- DataGridColumn.cs
- Int16AnimationUsingKeyFrames.cs
- XDeferredAxisSource.cs
- Int16.cs
- AncestorChangedEventArgs.cs