Archive for April, 2010

Logical vs Physical Addresses in WCF

April 18, 2010


In this example, I share a listenUri between two endpoints.

Synopsis:

We have one service implementation that has two service contracts.
Each service contract will have it’s own endpoint.
Each endpoint will share a listenUri.

We’ve also setup an endpoint for our metadata exchange.
I’ve done all of this imperatively.

Service code

using System.ServiceModel;
using System.ServiceModel.Description;

namespace Service
{
	[ServiceContract]
	public interface IGetHeaders
	{
		[OperationContract]
		string GetHeaders();
	}

	[ServiceContract]
	public interface ICalculate
	{
		[OperationContract]
		double Sum(double[] values);
	}

	public class HeaderService : IGetHeaders, ICalculate
	{
		public string GetHeaders()
		{
			return OperationContext.Current.RequestContext.RequestMessage.Headers.Action;
		}

		public double Sum(double[] values)
		{
			double result = 0.0;
			foreach (double value in values)
				result += value;
			return result;
		}
	}

	public class Program
	{
		public static void Main()
		{
			Uri baseAddress = new Uri("net.tcp://localhost:8241/Service");
			Uri listenUri = new Uri("net.tcp://localhost:8241/MyListenUri");

			ServiceHost serviceHost	= new ServiceHost(typeof(HeaderService), new Uri[] {baseAddress});
			NetTcpBinding netTcpBinding = new NetTcpBinding();

			serviceHost.AddServiceEndpoint(typeof(IGetHeaders),
				netTcpBinding, "/GetHeaders", listenUri);
			serviceHost.AddServiceEndpoint(typeof(ICalculate),
				netTcpBinding, "/Calculate", listenUri);

			ExposeMetadata(serviceHost);

				serviceHost.Open();
				Console.WriteLine("Host	running...");
			Console.WriteLine("Service {0} hosted and {1} to receive requests", serviceHost.Description.Name, serviceHost.State);
			Console.WriteLine("press Enter to terminate");
				Console.ReadLine();
				serviceHost.Close();
		}

		private static	void ExposeMetadata(ServiceHost serviceHost)
		{
			//Check	to see if the service host already has a ServiceMetadataBehavior
			ServiceMetadataBehavior	serviceMetadataBehavior	= serviceHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
			//If not, add one
			if(serviceMetadataBehavior == null)
				serviceMetadataBehavior	= new ServiceMetadataBehavior();
			serviceMetadataBehavior.HttpGetEnabled = true;
			Uri mexUri = new Uri("http://localhost:8242/Service/Mex");
			serviceMetadataBehavior.HttpGetUrl = mexUri;
			serviceMetadataBehavior.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
			serviceHost.Description.Behaviors.Add(serviceMetadataBehavior);
			//Add MEX endpoint
			serviceHost.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,	MetadataExchangeBindings.CreateMexHttpBinding(), mexUri);
		}
	}
}

Client code

using System;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace Client
{
	 class Program
	 {
		  static void Main(string[] args)
		  {
			NetTcpBinding netTcpBinding = new NetTcpBinding();
			Uri myListenUri = new Uri("net.tcp://localhost:8241/MyListenUri");

			ServiceProxy.GetHeadersClient getHeadersProxy =
				new ServiceProxy.GetHeadersClient(netTcpBinding, new EndpointAddress("net.tcp://localhost:8241/Service/GetHeaders"));
			getHeadersProxy.Endpoint.Behaviors.Add(new ClientViaBehavior(myListenUri));

			ServiceProxy.CalculateClient calculateProxy =
				new ServiceProxy.CalculateClient(netTcpBinding, new EndpointAddress("net.tcp://localhost:8241/Service/Calculate"));
			calculateProxy.Endpoint.Behaviors.Add(new ClientViaBehavior(myListenUri));

			Console.WriteLine("Press Enter to exercise GetHeaders");
			Console.ReadLine();
			Console.WriteLine("And the header is: {0}{1}", getHeadersProxy.GetHeaders(), Environment.NewLine);
			Console.WriteLine("Press Enter to exercise Sum");
			Console.ReadLine();
			Console.WriteLine("And the sum is: {0}{1}", calculateProxy.Sum(new double[] { 1.4, 3.5, 7.8 }), Environment.NewLine);
			Console.WriteLine("press Enter to terminate");
			Console.ReadLine();
		  }
	 }
}

Click on link below to download full source code.

public class Program
{
public    static void    Main()
{
Uri baseAddress =    new Uri(“net.tcp://localhost:8241/Service”);
Uri listenUri = new Uri(“net.tcp://localhost:8241/MyListenUri”);

ServiceHost    serviceHost    = new    ServiceHost(typeof(HeaderService), new    Uri[]    {baseAddress});
NetTcpBinding netTcpBinding =    new NetTcpBinding();

serviceHost.AddServiceEndpoint(typeof(IGetHeaders),
netTcpBinding,    “/GetHeaders”,    listenUri);
serviceHost.AddServiceEndpoint(typeof(ICalculate),
netTcpBinding,    “/Calculate”, listenUri);

ExposeMetadata(serviceHost);

serviceHost.Open();
Console.WriteLine(“Host    running…”);
Console.WriteLine(“Service    {0} hosted and    {1} to receive    requests”, serviceHost.Description.Name, serviceHost.State);
Console.WriteLine(“press Enter to terminate”);
Console.ReadLine();
serviceHost.Close();
}

private static    void ExposeMetadata(ServiceHost serviceHost)
{
//    Check    to    see if the service host    already has    a ServiceMetadataBehavior
ServiceMetadataBehavior    serviceMetadataBehavior    = serviceHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
//    If    not, add    one
if    (serviceMetadataBehavior == null)
serviceMetadataBehavior    = new    ServiceMetadataBehavior();
serviceMetadataBehavior.HttpGetEnabled    = true;
Uri mexUri = new Uri(“http://localhost:8242/Service/Mex&#8221;);
serviceMetadataBehavior.HttpGetUrl = mexUri;
serviceMetadataBehavior.MetadataExporter.PolicyVersion =    PolicyVersion.Policy15;
serviceHost.Description.Behaviors.Add(serviceMetadataBehavior);
//    Add MEX endpoint
serviceHost.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,    MetadataExchangeBindings.CreateMexHttpBinding(), mexUri);
}
}

SingleServiceListenUriTwoEndpoints.zip – 20.98 KB

Once you’ve built the solution, navigate to
Service\bin\Debug\Service.exe and run it.
You should see output like the following.

Now run the Client project in the debugger.
You should see output like the following, once you’ve hit Enter twice.

This is also a good read on the differences between
Logical vs. Physical Addresses.

Advertisements

Exam Prep on Bindings according to Exam Tip in MCTS Training Kit

April 11, 2010

According to the Exam Tip on pg 236 of the MCTS Self-Paced Training Kit (Exam 70-503)
The type of questions that may arise around bindings are:

1. The difference between duplex and nonduplex.
2. The support for different authentication types.
3. The ability to provide reliable message delivery.

My research:

1. Bindings that support duplex communication natively:

Tcp bindings
Named pipe bindings
WSDualHttpBinding

2. Support for different Authentication types:

The Security member on the bindings provide access to the SecurityBindingElement subclass’s.
I haven’t seen a binding without authentication support.
Example of authentication members hierarchy on BasicHttpBinding, WSHttpBinding.

BasicHttpBinding
+ Security – returns BasicHttpSecurity
——+ Message – returns BasicHttpMessageSecurity
———+ ClientCredentialType – returns BasicHttpMessageCredentialType
————+ UserName or
————+ Certificate
——+ Mode – returns BasicHttpSecurityMode
———+ None or
———+ Transport or
———+ Message or
———+ TransportWithMessageCredential or
———+ TransportCredentialOnly
——+ Transport – returns HttpTransportSecurity
———+ ClientCredentialType – returns HttpClientCredentialType
————+ None or
————+ Basic or
————+ Digest or
————+ Ntlm or
————+ Windows or
————+ Certificate
———+ ProxyCredentialType – returns HttpProxyCredentialType
————+ None or
————+ Basic or
————+ Digest or
————+ Ntlm or
————+ Windows
———+ Realm

WSHttpBinding
+ Security – returns WSHttpSecurity
——+ Message – returns NonDualMessageSecurityOverHttp
———+ ClientCredentialType – returns MessageCredentialType
————+ None or
————+ Windows or
————+ UserName or
————+ Certificate or
————+ IssuedToken
———+ EstablishSecurityContext – returns bool
———+ NegotiateServiceCredential – returns bool
——+ Mode – returns SecurityMode
———+ None or
———+ Transport or
———+ Message or
———+ TransportWithMessageCredential
——+ Transport – returns HttpTransportSecurity
———+ ClientCredentialType – returns HttpClientCredentialType
————+ None or
————+ Basic or
————+ Digest or
————+ Ntlm or
————+ Windows or
————+ Certificate
———+ ProxyCredentialType – returns HttpProxyCredentialType
————+ None or
————+ Basic or
————+ Digest or
————+ Ntlm or
————+ Windows
———+ Realm

3. Ability to provide reliable message delivery:

Reliable message delivery is provided by way of the ReliableSessionBindingElement.
The bindings that have this binding element provide access to it via the ReliableSession property on the binding.
Which allows the developer/administrator to turn on/off WS-ReliableMessaging.
The binding matrix shows which bindings support reliable messaging.
Supported bindings are:
WsHttpBinding (off by default),
WsDualHttpBinding (on by default),
NetTcpBinding (off by default).

A few steps to secure a FreeNAS server

April 6, 2010

Change the web gui admin user name in System|General under WebGUI->Username.

Change the default password in System|General|Password.

Setup key pair authentication for SSH and secure FreeNAS.

Clean out any existing files in ~/.ssh on your client machine.
At command prompt on client:

$ ssh-keygen -t rsa

agree to location that ssh-keygen wants to store the keys… ~/.ssh
Enter a pass phrase twice to confirm. This is the pass phrase for the public key.
Keys are now in ~/.ssh

I created the home directory in /mnt/FileServer and chown’d it to root:wheel.

mkdir /mnt/FileServer/home
chown root:wheel /mnt/FileServer/home

Created the myuser directory in /mnt/FileServer/home.
In the web UI Access|Users|Edit for my user. I set the Home directory to /mnt/FileServer/home/myuser/
The reason we can’t use the default ~ directory of /mnt is because everything in front of /mnt/FileServer (the mount point of my RAID) is part of the FreeNAS ROM.
It’s destroyed on each reboot. Matt Rude brought this to my attention here
Log in to FreeNAS using SSH

ssh myuser@nameoffileserver

create the .ssh directory on /mnt/FileServer/home/myuser/
as myuser, create the authorized_keys file in /mnt/FileServer/home/myuser/.ssh if it doesn’t already exist

$ touch authorized_keys

Copy the public key to the file server

scp ~/.ssh/id_rsa.pub myuser@nameoffileserver:

Make sure you have the collan at the end of the above command, else the file won’t be copied.
Type yes to the prompt that the authenticity of the server you are tryign to scp to can’t be established and you want to continue.
The server you are trying to connect to is added to the list of known hosts on the local machine.
Thats /home/myuser/.ssh/known_hosts
On the server, from the ~ directory (thats /mnt/FileServer/home/myuser in our case)
The public key needs to be put into the list of authorized clients that may connect to the sshd.

$ cat id_rsa.pub >> .ssh/authorized_keys

Although this is a better way to copy the public key:

ssh-copy-id MyUserName@MyWindows7Box

We need to change some permissions on…
your home directory on the server (/mnt/FileServer/home/myuser) may have the wrong permissions. We need to remove the write perms for group and other.

$ su root
# chmod go-w /mnt/FileServer/home/myuser

The /mnt/FileServer/home/myuser/.ssh currently had 755 so

# chmod go-w /mnt/FileServer/home/myuser/.ssh

had no effect.
/mnt/FileServer/home/myuser/.ssh/authorized_keys needed to be chmod 600. In fact anything/everything in the ~/.ssh dir (if there is anything else) needs to be chmod 600

Also need to

nameoffileserver:/mnt/FileServer/home/myuser/.ssh# chown myuser authorized_keys

We can now remove the ~/id_rsa.pub from the server, now that the key is in ~/.ssh/authorized_keys

$ rm ~/id_rsa.pub

Should now be able to log in using key pair authentication.

Turn password authentication off, and changed the default ssh port in the web gui Services|SSH.

Turned ssl on to access the web gui in System|General Setup.

When I open up the FreeNAS server to the internet, it’ll be by way of SSH tunnel rather than just opening up the firewall to https to the server.

Looks like there is a pretty simple guide here to do that.

Used the following resources:

http://www.learnfreenas.com/blog/
http://phanvinhthinh.blogspot.com/2010/02/how-to-secure-your-freenas-server.html
http://www.freenaskb.info/kb/?View=entry&EntryID=257
http://www.learnfreenas.com/blog/2009/07/22/how-to-connect-to-your-freenas-server-via-ssh-without-a-password-password-free-logins-via-public-key-authentication/
http://www.freebsd.org/doc/en/articles/committers-guide/ssh.guide.html

Built-in MSMQ Bindings

April 5, 2010

NetMsmqBinding, MsmqIntegrationBinding.

NetMsmqBinding only works if you have WCF on both sides of the Queue-to-Queue transfer.

MsmqIntegrationBinding is targeted toward existing MSMQ applications that use COM, native C++ APIs or the types defined in the System.Messaging namespace (as stated by MSDN).

.

Messages from one of the bindings are not compatible with the other binding type.

MsmqIntegrationBinding uses a pre-WCF serialization format, by way of the SerializationFormat property, which is of type enum MsmqMessageSerializationFormat.

The members being: Xml, Binary, ActiveX, ByteArray, Stream.

.

NetMsmqBinding has the following 2 binding elements:

MsmqIntegrationBinding has only one binding element:

BinaryMessageEncodingBindingElement.MessageVersion which is only available on the NetMsmqBinding specifies the WCF supported versioning information.

How do we set the security mode on the standard msmq bindings?

NetMsmqBinding.Security gets the NetMsmqSecurity associated with this binding.
MsmqIntegrationBinding.Security gets the MsmqIntegrationSecurity associated with this binding.

NetMsmqSecurity has the following properties:
Message, Mode, Transport.
MsmqIntegrationSecurity has the following properties:
Mode, Transport.

The Mode properties return the security modes…
MsmqIntegrationSecurityMode in the case of MsmqIntegrationSecurity.Mode.
NetMsmqSecurityMode in the case of NetMsmqSecurity.Mode.

Imperatively set security mode:

Declaratively set security mode:

<configuration>
   <system.ServiceModel>
      <bindings>
         <netMsmqBinding>
            <binding name="MyNetMsmqBinding">
               <security mode="Message"/>
            </binding>
         </netMsmqBinding>
         <msmqIntegrationBinding>
            <binding name="MyMsmqIntegrationBinding">
               <security mode="Transport"/>
            </binding>
         </msmqIntegrationBinding>
      </bindings>
   </system.ServiceModel>
</configuration>

According to this MSDN post, it appears as if the default security mode is Message for NetMsmqBinding and Transport for MsmqIntegrationBinding.

The default security mode for both NetMsmqBinding and MsmqIntegrationBinding is Transport.




-



-