I was particularly interested to try this with TCP binding and it looks like custom binding is the only way.
For the http I started with the Federated HTTP binding, but since the custom binding took shape, you get more control this way, so I formulated an https equivalent here too.
Note this is for illustration purposes it's certainly not production ready.
1. Get token from ACS
private static SecurityToken GetIdentityProviderToken(string acsEndpoint, string serviceEndpoint) { var factory = new WSTrustChannelFactory(new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential), acsEndpoint) { TrustVersion = TrustVersion.WSTrust13 }; factory.Credentials.ClientCertificate.SetCertificate( StoreLocation.LocalMachine, StoreName.My, X509FindType.FindBySubjectName, "[cert dns/hostname]"); var rst = new RequestSecurityToken { RequestType = RequestTypes.Issue, AppliesTo = new EndpointAddress(serviceEndpoint), //specify URI realm that ACS token will apply to //AppliesTo = new EndpointAddress( new Uri( "urn:federation:customer:222:agent:11" ) ), KeyType = KeyTypes.Symmetric }; factory.Credentials.UserName.UserName = ClientUsername; factory.Credentials.UserName.Password = ClientPassword; var channel = factory.CreateChannel(); return channel.Issue(rst); }2. Http Client config (code)
private static ChannelFactory3. TCP Client config (code)GetCustomHttpBoundService (SecurityToken token, string address) { var securityBootStrap = SecurityBindingElement.CreateIssuedTokenForCertificateBindingElement(new IssuedSecurityTokenParameters()); var security = SecurityBindingElement.CreateSecureConversationBindingElement(securityBootStrap, requireCancellation: true); Console.WriteLine("Include timestamp " + security.IncludeTimestamp); Console.WriteLine("Allow insecure transport " + security.AllowInsecureTransport); Console.WriteLine("Client: Detect replays " + security.LocalClientSettings.DetectReplays); Console.WriteLine("Client: Max clock skew " + security.LocalClientSettings.MaxClockSkew); Console.WriteLine("Server: Detect replays " + security.LocalServiceSettings.DetectReplays); Console.WriteLine("Server: Max clock skew " + security.LocalServiceSettings.MaxClockSkew); var customBinding = new CustomBinding(new List { security, new BinaryMessageEncodingBindingElement(), new HttpsTransportBindingElement() }); var factory = new ChannelFactory (customBinding, new EndpointAddress(new Uri(address), EndpointIdentity.CreateDnsIdentity("[cert dns/hostname]"))); factory.ConfigureChannelFactory(); Debug.Assert(factory.Credentials != null); factory.Credentials.SupportInteractive = false; factory.Credentials.ServiceCertificate.SetDefaultCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindBySubjectName, "[cert dns/hostname]"); return factory; }
private static ChannelFactory4. Http Server configGetCustomTcpBoundService (SecurityToken token, string address) { var securityBootStrap = SecurityBindingElement.CreateIssuedTokenForCertificateBindingElement(new IssuedSecurityTokenParameters()); var security = SecurityBindingElement.CreateSecureConversationBindingElement(securityBootStrap, requireCancellation: true); Console.WriteLine("Include timestamp " + security.IncludeTimestamp); Console.WriteLine("Allow insecure transport " + security.AllowInsecureTransport); Console.WriteLine("Client: Detect replays " + security.LocalClientSettings.DetectReplays); Console.WriteLine("Client: Max clock skew " + security.LocalClientSettings.MaxClockSkew); Console.WriteLine("Server: Detect replays " + security.LocalServiceSettings.DetectReplays); Console.WriteLine("Server: Max clock skew " + security.LocalServiceSettings.MaxClockSkew); var customBinding = new CustomBinding(new List { security, new BinaryMessageEncodingBindingElement(), new SslStreamSecurityBindingElement {RequireClientCertificate = false}, new TcpTransportBindingElement() }); var factory = new ChannelFactory (customBinding, new EndpointAddress( new Uri(address), EndpointIdentity.CreateDnsIdentity("[cert dns/hostname]"))); factory.ConfigureChannelFactory(); Debug.Assert(factory.Credentials != null); factory.Credentials.SupportInteractive = false; factory.Credentials.ServiceCertificate.SetDefaultCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindBySubjectName, "[cert dns/hostname]"); return factory; }
<binding name="customfedhttps"> <security authenticationmode="SecureConversation" requiresecuritycontextcancellation="true"> <secureconversationbootstrap authenticationmode="IssuedTokenForCertificate"> </secureconversationbootstrap> </security> <binarymessageencoding> <httpstransport requireclientcertificate="false"> </httpstransport></binarymessageencoding> </binding>5. TCP Server config
<binding name="customfedtcp"> <security authenticationmode="SecureConversation" requiresecuritycontextcancellation="true"> <secureconversationbootstrap authenticationmode="IssuedTokenForCertificate"> </secureconversationbootstrap> </security> <binarymessageencoding> <sslstreamsecurity requireclientcertificate="false"> <tcptransport> </tcptransport></sslstreamsecurity></binarymessageencoding> </binding>6. Server behaviour
<behaviors> <servicebehaviors> <behavior name="fedbehaviour"> <servicemetadata httpsgetenabled="true"> <federatedservicehostconfiguration> </federatedservicehostconfiguration></servicemetadata></behavior> </servicebehaviors> </behaviors> <extensions> <behaviorextensions> <add name="federatedServiceHostConfiguration" type="Microsoft.IdentityModel.Configuration.ConfigureServiceHostBehaviorExtensionElement, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"> </add></behaviorextensions> </extensions>7. Identity model config
<microsoft.identitymodel> <service> <audienceuris> <add value="https://localhost/Service1.svc"> <add value="net.tcp://localhost:997/Service2.svc"> </add></add></audienceuris> <servicecertificate> <certificatereference findvalue="[cert dns/hostname]" storelocation="LocalMachine" storename="My" x509findtype="FindBySubjectName"> </certificatereference></servicecertificate> <issuernameregistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"> <trustedissuers> <add name="[cert dns/hostname]" thumbprint="[cert thumb print]"> </add></trustedissuers> </issuernameregistry> <certificatevalidation certificatevalidationmode="None"> </certificatevalidation></service> </microsoft.identitymodel>Useful links:
No comments:
Post a Comment