SslStreamSecurityBindingElement Class

Definition

Represents a custom binding element that supports channel security using an SSL stream.

public ref class SslStreamSecurityBindingElement : System::ServiceModel::Channels::BindingElement
public ref class SslStreamSecurityBindingElement : System::ServiceModel::Channels::StreamUpgradeBindingElement
public ref class SslStreamSecurityBindingElement : System::ServiceModel::Channels::StreamUpgradeBindingElement, System::ServiceModel::Channels::ITransportTokenAssertionProvider, System::ServiceModel::Description::IPolicyExportExtension
public class SslStreamSecurityBindingElement : System.ServiceModel.Channels.BindingElement
public class SslStreamSecurityBindingElement : System.ServiceModel.Channels.StreamUpgradeBindingElement
public class SslStreamSecurityBindingElement : System.ServiceModel.Channels.StreamUpgradeBindingElement, System.ServiceModel.Channels.ITransportTokenAssertionProvider, System.ServiceModel.Description.IPolicyExportExtension
type SslStreamSecurityBindingElement = class
    inherit BindingElement
type SslStreamSecurityBindingElement = class
    inherit StreamUpgradeBindingElement
type SslStreamSecurityBindingElement = class
    inherit StreamUpgradeBindingElement
    interface ITransportTokenAssertionProvider
    interface IPolicyExportExtension
Public Class SslStreamSecurityBindingElement
Inherits BindingElement
Public Class SslStreamSecurityBindingElement
Inherits StreamUpgradeBindingElement
Public Class SslStreamSecurityBindingElement
Inherits StreamUpgradeBindingElement
Implements IPolicyExportExtension, ITransportTokenAssertionProvider
Inheritance
SslStreamSecurityBindingElement
Inheritance
SslStreamSecurityBindingElement
Implements

Remarks

Transports that use a stream-oriented protocol such as TCP and named pipes support stream-based transport upgrades. Specifically, Windows Communication Foundation (WCF) provides security upgrades. The configuration of this transport security is encapsulated by this class as well as by SslStreamSecurityBindingElement, which can be configured and added to a custom binding. In addition, a third party can write their own custom StreamSecurityBindingElement. These binding elements extend the StreamUpgradeBindingElement class that is called to build the client and server stream upgrade providers.

A custom binding contains a collection of binding elements arranged in a specific order: the element that represents the top of the binding stack is added first, the next element down in the binding stack is added second, and so on.

To add this class to a binding

  1. Create a BindingElementCollection.

  2. Create custom binding elements that are above this binding element in the binding stack, such as the optional TransactionFlowBindingElement and ReliableSessionBindingElement.

  3. Add the created elements in the order described previously to the BindingElementCollection using the InsertItem method.

  4. Create an instance of SslStreamSecurityBindingElement and add it to the collection.

  5. Add any additional custom binding elements to the collection, such as TcpTransportBindingElement.

There are three scenarios in which you must either manually specify the correct UPN/SPN on the client endpoint after importing the WSDL, or specify a custom IdentityVerifier on the client's SslStreamSecurityBindingElement.

  1. No service identity is published in WSDL. SspiNegotiatedOverTransport and HTTPS are used (for example, a WSHttpBinding with SecurityMode = TransportWithMessageCredential). If the service is not running with the machine identity, you must manually specify the correct UPN/SPN on the client endpoint after importing the WSDL.

  2. DNS service identity is published in WSDL. SspiNegotiatedOverTransport and SslStreamSecurityBindingElement are used (for example, NetTcpBinding with SecurityMode = TransportWithMessageCredential) instead of a UPN/SPN. If the service is not running with the machine identity, or the DNS identity is not the machine's identity, you must manually specify the correct UPN/SPN on the client endpoint after importing the WSDL.

  3. DNS identity is published in WSDL. If SslStreamSecurityBindingElement is overridden on the client, you must specify a custom IdentityVerifier on the client's SslStreamSecurityBindingElement.

The following code shows how to manually specify the correct UPN/SPN on the client endpoint, as well as how to specify a custom IdentityVerifier on the client's SslStreamSecurityBindingElement.

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Net;  
using System.IdentityModel.Claims;  
using System.IdentityModel.Policy;  
using System.Security.Cryptography.X509Certificates;  
using System.ServiceModel;  
using System.ServiceModel.Channels;  
using System.ServiceModel.Description;  
using System.ServiceModel.Security;  
using System.Xml;  

namespace ServiceNamespace  
{  
    [ServiceContract]  
    interface IService  
    {  
        [OperationContract]  
        void DoSomething();  
    }  

    class DnsIdentityVerifier : IdentityVerifier  
    {  
        DnsEndpointIdentity _expectedIdentity;  

        public DnsIdentityVerifier(EndpointAddress serviceEndpoint)  
        {  
            _expectedIdentity = new DnsEndpointIdentity(serviceEndpoint.Uri.DnsSafeHost);  
        }  

        public override bool CheckAccess(EndpointIdentity identity, AuthorizationContext authContext)  
        {  
            Claim dnsClaim = authContext.Claims().Single(claim => claim.ClaimType == ClaimTypes.Dns);  
            return String.Equals(_expectedIdentity.IdentityClaim.Resource, dnsClaim.Resource);  
        }  

        public override bool TryGetIdentity(EndpointAddress reference, out EndpointIdentity identity)  
        {  
            identity = _expectedIdentity;  
            return true;  
        }  
    }  

    static class LinqExtensionForClaims  
    {  
        public static IEnumerable<Claim> Claims(this AuthorizationContext authContext)  
        {  
            if (null != authContext.ClaimSets)  
            {  
                foreach (ClaimSet claimSet in authContext.ClaimSets)  
                {  
                    if (null != claimSet)  
                    {  
                        foreach (Claim claim in claimSet)  
                        {  
                            yield return claim;  
                        }  
                    }  
                }  
            }  
        }  
    }  

    class Service : IService  
    {  
        public void DoSomething()  
        {  
            Console.WriteLine("Service called.");  
        }  
    }  

    class Program  
    {  
        static void Main(string[] args)  
        {  
            string hostname = Dns.GetHostEntry(String.Empty).HostName;  
            NetTcpBinding serviceBinding = new NetTcpBinding(SecurityMode.TransportWithMessageCredential);  

            ServiceHost serviceHost = new ServiceHost(typeof(Service), new Uri(String.Format("net.tcp://{0}:8080/Service", hostname)));  
            serviceHost.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, "8a 42 1b eb cf 8a 14 b1 de 83 d9 a5 70 88 0a 62 f9 bf 69 06");  
            ServiceEndpoint serviceEndpoint = serviceHost.AddServiceEndpoint(typeof(IService), serviceBinding, "Endpoint");  
            serviceHost.Open();  

            CustomBinding clientBinding = new CustomBinding(serviceBinding.CreateBindingElements());  
            SslStreamSecurityBindingElement sslStream = clientBinding.Elements.Find<SslStreamSecurityBindingElement>();  
            sslStream.IdentityVerifier = new DnsIdentityVerifier(serviceEndpoint.Address);  

            ChannelFactory<IService> channelFactory = new ChannelFactory<IService>(clientBinding, new EndpointAddress(serviceEndpoint.Address.Uri, UpnEndpointIdentity.CreateUpnIdentity("username@domain")));  
            channelFactory.Credentials.Windows.AllowNtlm = false;  
            IService channel = channelFactory.CreateChannel();  
            channel.DoSomething();  
        }  
    }  

Constructors

SslStreamSecurityBindingElement()

Initializes a new instance of the SslStreamSecurityBindingElement class.

SslStreamSecurityBindingElement(SslStreamSecurityBindingElement)

Initializes a new instance of the SslStreamSecurityBindingElement class using the values from another SslStreamSecurityBindingElement.

Properties

IdentityVerifier

Gets or sets the identity verifier for this binding.

RequireClientCertificate

Gets or sets a value that specifies whether a client certificate is required for this binding.

SslProtocols

Specifies the list of SSL/TLS protocols to negotiate when using a client credential type of TcpClientCredentialType.Certificate. The value can be a combination of one of more of the following enumeration members: Ssl3, Tls, Tls11, Tls12.

Methods

BuildChannelFactory<TChannel>(BindingContext)

Creates a channel factory of a specified type.

BuildChannelListener<TChannel>(BindingContext)

Creates a channel listener of a specified type.

BuildChannelListener<TChannel>(BindingContext)

Initializes a channel listener to accept channels of a specified type from the binding context.

(Inherited from BindingElement)
BuildClientStreamUpgradeProvider(BindingContext)

Creates an instance on the client of the StreamUpgradeProvider based on the channel context provided.

BuildServerStreamUpgradeProvider(BindingContext)

Creates an instance on the server of the StreamUpgradeProvider based on the channel context provided.

BuildServerStreamUpgradeProvider(BindingContext)

Creates an instance on the server of the StreamUpgradeProvider based on the channel context provided.

(Inherited from StreamUpgradeBindingElement)
CanBuildChannelFactory<TChannel>(BindingContext)

Gets a value that indicates whether a channel factory of the specified type can be built.

CanBuildChannelListener<TChannel>(BindingContext)

Gets a value that indicates whether a channel listener of the specified type can be built.

CanBuildChannelListener<TChannel>(BindingContext)

Returns a value that indicates whether the binding element can build a listener for a specific type of channel.

(Inherited from BindingElement)
Clone()

Creates a new instance that is a copy of the current instance.

Equals(Object)

Determines whether the specified object is equal to the current object.

(Inherited from Object)
GetHashCode()

Serves as the default hash function.

(Inherited from Object)
GetProperty<T>(BindingContext)

Gets a specified object from the BindingContext.

GetTransportTokenAssertion()

Gets the XmlElement that represents the transport token used in the security binding.

GetType()

Gets the Type of the current instance.

(Inherited from Object)
MemberwiseClone()

Creates a shallow copy of the current Object.

(Inherited from Object)
ShouldSerializeIdentityVerifier()

Gets a value that indicates whether the identify verifier should be serialized.

ToString()

Returns a string that represents the current object.

(Inherited from Object)

Explicit Interface Implementations

IPolicyExportExtension.ExportPolicy(MetadataExporter, PolicyConversionContext)

Exports a custom policy assertion about bindings.

Applies to