Monday, February 28, 2011

Using X509 Certificates with WCF

I can't say whenever I need to use X509 certificates I've found it easy and straight forward. But unless you have the luxury of using Https you should be using X509 certificates to encrypt the message payload. I have also heard a strong argument to encrypt the message content even under https. Https encryption can be stripped at a firewall or proxy appliance (a few years ago I saw a Microsoft ISA solution that did). So in between the proxy server and the destination service server its unencrypted; not a big risk but nonetheless.

During development you can generate your own X509 certificates using the Makecert Visual Studio command line tool. (Its like Bear Grylls saying insects are a better source of protein and you can live off them; you can but it tastes like....) So a better tool is PluralSight's Self-Cert. In production ideally it would be best to have a certificate issued by a trusted certificate authority like Thwart or Verisign. But sometimes spending the money on a fully trusted certificate might be overkill. I am currently writing an intranet based service component using TCP/IP, so self-generated certificates should be fine. Web Browsers will give ugly warning errors for unofficial self-generated certificates, but given I'm writing both the consumer and the service it will be fine. You wouldn't get away with this in a Silverlight scenario.

Adding a X509 certificate to your service is pretty easy once you know where and how. The first step is to generate one using MarkCert or Self-Cert. Using Self-Cert is easier, and at the same time it registers it in the Windows Certificate store. If it is not registered in the Certificate store it won't do its job.

Secondly, simply add it to the app.config:

<?xmlversion="1.0"?><configuration><system.serviceModel><services><servicename="Service.CalculatorService"behaviorConfiguration="CalculatorServiceBehavior"><endpointbinding="netTcpBinding"bindingConfiguration="Binding1"contract="Service.ICalculator"name="NetTcpEndpoint"><identity><dnsvalue="TestKeyAuthentication"/><!-- This matches the x509 certificate name --></identity></endpoint><endpointaddress="mex"binding="mexTcpBinding"name="NetTcpMetadataPoint"contract="IMetadataExchange"/><host><baseAddresses><addbaseAddress="net.tcp://localhost:9000/service/UserNamePasswordValidator"/></baseAddresses></host></service></services><bindings><netTcpBinding><bindingname="Binding1"><securitymode="Message"><messageclientCredentialType="UserName"/></security></binding></netTcpBinding></bindings><behaviors><serviceBehaviors><behaviorname="CalculatorServiceBehavior"><serviceMetadatahttpGetEnabled="false"/><serviceDebugincludeExceptionDetailInFaults="false"/><serviceCredentials><!-- The serviceCredentials behavior allows one to specify a custom validator for username/password combinations. --><userNameAuthenticationuserNamePasswordValidationMode="Custom"customUserNamePasswordValidatorType="Service.CustomUserNameValidator, Service"/><!-- The serviceCredentials behavior allows one to define a service certificate. A service certificate is used by a client to authenticate the service and provide message protection. This configuration references the "localhost" certificate installed during the setup instructions. --><serviceCertificatefindValue="TestKeyAuthentication"storeLocation="LocalMachine"storeName="AuthRoot"x509FindType="FindBySubjectName"/></serviceCredentials></behavior></serviceBehaviors></behaviors></system.serviceModel></configuration>

The key element is <serviceCertificate />. The Findvalue attribute is the "common name" of the certificate (Self-Cert calls it distinguished name).

For a full working example see this post.

If your using callbacks (aka duplex) then you should add the client certificate to the service app.config as well. This is so when the service is calling the client back on the callback contract it can encrypt the message. (In an ordinary request/response call the client has its own certificate and also the service's certificate from proxy generation time so it can encrypt, but the service has no knowledge of the client upfront).


<clientCertificate><certificatefindValue="TestKeyAuthentication"storeLocation="LocalMachine"storeName="AuthRoot"x509FindType="FindBySubjectName"/></clientCertificate>Add this element under the <serviceCertficate /> element as a sibling to it.

I'll update this post if I run into any problems with deploying using self generated certificates.

Saturday, February 26, 2011

WCF Security: NetTcpBinding with custom UserName/Password authentication

I've been thinking for some time about getting a basic working example of WCF Security using netTcpBinding with custom UserName authentication.  There seems to be plenty of examples using Http flavoured bindings all over the net, but not many for netTcpBinding.

By default WCF will always pass through windows credentials if calling from a .Net based client. (I'm not sure what happens in Silverlight, it would be interesting to know).  In a perfect world every user has their own AD user and they user it to log into their Windows PC.  They know keeping the password safe and secure is important.  Unfortunately we don't live in a perfect world.  Some companies have one AD log-on per job role, especially if that role is contract or seasonal based.  So this effectively means using Windows authentication for a WCF service in this scenario won't work.

I need to be able to identify an incoming call into a service using a custom authentication credential, something the software application is in control of.  The AD System Administrator may be too lazy to create a log-on per user, but to use any software application that requires authentication and authorization, laziness doesn't cut it.

Here's a working example of using netTcpBinding that uses "UserName" authentication.
Download the code here.

The most exciting part is the app.config of the service:

<?xml version="1.0"?>
<configuration>
    <system.serviceModel>
        <services>
            <service
                name="Service.CalculatorService"
                behaviorConfiguration="CalculatorServiceBehavior">
                <endpoint
                    binding="netTcpBinding"
                    bindingConfiguration="Binding1"
                    contract="Service.ICalculator"
                    name="NetTcpEndpoint">
                    <identity>
                        <dns value="TestKeyAuthentication" /> <!-- This matches the x509 certificate name -->
                    </identity>
                </endpoint>
                <endpoint
                    address="mex"
                    binding="mexTcpBinding"
                    name="NetTcpMetadataPoint"
                    contract="IMetadataExchange" />
                <host>
                    <baseAddresses>
                        <add baseAddress="net.tcp://localhost:9000/service/UserNamePasswordValidator"/>
                    </baseAddresses>
                </host>
            </service>
        </services>

        <bindings>
            <netTcpBinding>
                <binding name="Binding1">
                    <security mode="Message">
                        <message clientCredentialType="UserName"/>
                    </security>
                </binding>
            </netTcpBinding>
        </bindings>

        <behaviors>
            <serviceBehaviors>
                <behavior name="CalculatorServiceBehavior">
                    <serviceMetadata httpGetEnabled="false"/>
                    <serviceDebug includeExceptionDetailInFaults="false"/>
                    <serviceCredentials>
                        <!-- 
                        The serviceCredentials behavior allows one to specify a custom validator for username/password combinations.                  
                        -->
                        <userNameAuthentication
                            userNamePasswordValidationMode="Custom"
                            customUserNamePasswordValidatorType="Service.CustomUserNameValidator, Service"/>
                        <!-- 
                        The serviceCredentials behavior allows one to define a service certificate.
                        A service certificate is used by a client to authenticate the service and provide message protection.
                        This configuration references the "localhost" certificate installed during the setup instructions.
                        -->
                        <serviceCertificate
                            findValue="TestKeyAuthentication"
                            storeLocation="LocalMachine"
                            storeName="AuthRoot"
                            x509FindType="FindBySubjectName"/>
                        <clientCertificate>
                            <certificate
                                findValue="TestKeyAuthentication"
                                storeLocation="LocalMachine"
                                storeName="AuthRoot"
                                x509FindType="FindBySubjectName"/>
                        </clientCertificate>

                    </serviceCredentials>
                </behavior>
            </serviceBehaviors>
        </behaviors>

    </system.serviceModel>
</configuration>

There's a couple of things of note:
The endpoints and service declaration itself is stock standard, apart from the identity element.  This tells the service to use the x509 certificate as its identity. This effectively means that something else cannot spoof the service, the client will know because the spoof will not have the x509 certificate. The text in this element should match the certificate name. Read more about certificates in another post here.

In Binding declaration you can specify the security mode. By default I believe this defaults to "Transport". Tcp/Ip does not have UserName/Password style transport layer security like Http has, so "Message" is your only other option. It does allow you to use "Transport" as an option but this relies completely on certificates for authentication. Not a reasonable demand I can place on my service users.  Interestingly there is no support for Message security in netNamedPipeBinding, which I found quite surprising, I can't see why this shouldn't be allowed.
[Edit: This from Juval Lowy's Programming WCF Book: "Note that netNamedPipeBinding only supports None and Transport security- there is no sense in using Message security over IPC, since with IPC you have exactly one hop from client to service." Message security is intended to provide a secure transmission over an unsecured transport like Tcp/Ip or Http etc.]

The real magic happens in the Binding Configuration. It has an element "serviceCredentials" which allows you to customise the mechanism that authenticates incoming calls.  The element to focus on is "userNameAuthentication". This points to a public creatable type that inherits System.IdentityModel.Selectors.UserNamePasswordValidator.  This class has a method you must override call Validate(string userName, string password).  To deny users access you throw a FaultException.


namespace Service
{
    using System;
    using System.ServiceModel;

    public class CustomUserNameValidator : System.IdentityModel.Selectors.UserNamePasswordValidator
    {
        public override void Validate(string userName, string password)
        {
            if (null == userName || null == password)
            {
                throw new ArgumentNullException();
            }

            var authentication = new Authentication();
            var succeeded = authentication.LogOnUser(userName, password);

            if (succeeded <= 0)
            {
                throw new FaultException("Unknown Username or Incorrect Password");
            }
        }
    }
}


Lastly, here is the certificate declarations.  The "serviceCertificate" element causes WCF to go to the certificate store and find a certificate to use service-side. This prevents malicious software from spoofing the service.  It also allows encryption of all data sent client to server and back to ensure any intermediary cannot sniff the data and see username's password's etc.  Without certificates this would create a significant security flaw, intercepting an examining the binary payload of a tcp/ip packet is not that difficult.  The "clientCertificate" element defines the certificate the client will be using to allow duplex channels to be encrypted. If your service has duplex contracts you need to specify the certificate up front. In a normal request response scenario the client attaches their certificate to all requests and the service has it to encrypt its response. In a duplex callback scenario there is no request, so the service needs to have the client's certificate stored in advance.  In my example here all clients will use the same certificate.

My intention is to generate my own x509 certificates and include them in an installer package to be registered with the local machine certificate store during install.

The great thing about WCF security model is that it is disconnected from your service implementation. Changing the service authentication mode at a later stage is as simple as changing the app.config, no code to change.

When a service call is received by your service contract implementation, you can retrieve the user like this:

var x = ServiceSecurityContext.Current.PrimaryIdentity;


Unfortunately, this only gives you a GenericIdentity object which contains simple the UserName, and Password as strings.  In a future enhancement to this post I'll show how to add more payload data.

To make a call to a secured service you now need to pass in credentials with each invocation, like this:

var proxy = new Service.CalculatorClient();
            if (proxy.ClientCredentials == null)
            {
                throw new NotSupportedException("Client Credentials are null.");
            }

            proxy.ClientCredentials.UserName.UserName = username;
            proxy.ClientCredentials.UserName.Password = password;


Thanks to Marjorie for helping me prepare this. :-)

References.

Wednesday, February 23, 2011

Technical Debt vs Code Debt

I really like the distinction Steve Johnson makes in his article about Technical versus Code Debt.  Its a worthwhile distinction I think because it hints at the type or person required to do the clean up.  He defines Technical Debt as sloppy or too quick architecture or design that results in poor performance (scalability, throughput or extensibility).  Code Debt is defined as implementation problems of an otherwise adequate architecture and design. This code mean poor understanding, communication or lack of experience and skill. Or even more simply, lack of adequate code review.

One remedy for this is finding quick and easy analysis and metrics tools.  For example, NDepend, or Visual Studio's (Premium and better) Code Analysis and Metrics.  Visual Studio Ultimate also has a neat auto-diagram generation tool to show Type Sequence Diagrams (sometimes called type interaction diagrams but gets confused with UX Interaction Diagrams).  I'm also on the hunt for a good class diagram generator, (currently looking at Vs Ultimate class diagrams, but seems a little manual; and also ModelMaker).

Steve also suggests creating a "System Persona" to add value to the debt story and help you evaluate ROI.

BadFormatException / FileLoadException

Today I had an issue where an application was throwing "BadFormatException" on a 64bit machine and on a 32bit machine "FileLoadException".

The exception message was:

Mixed mode assembly is built against version 'v2.0.50727' of the runtime and cannot be loaded in the 4.0 runtime without additional configuration information.

Although I've seen this before and new it was because by default .NET will not let you mix different versions of the runtime in multiple dependencies, it took me a few moments to google it. So I thought I'd put it here for quick reference. For example, if you are referencing a 2.0 DLL from a 4.0 application by default you will get an exception the first time you try to access the 2.0 DLL. Unless you choose to allow multiple run-times.

Add the following to your app.config:
 <startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0"/>
</startup>

WCF Authentication with netTcpBinding

A colleague and I are currently working through a bunch of scenarios for WCF Authentication and Authorisation using netTcpBinding.  All scenarios involve an intranet application or inter-process communication within the same machine.  This being the case I'd like to use netTcpBinding or netNamedPipes if possible, and avoid Http.  Most examples seem to talk about Http, and Windows Authentication, but in my case I cannot guarantee there is an Active Directory Domain, or that each user is using unique credentials (some users share log-on ids... yes don't get me started).

So this is a work in progress at the moment, and I need a central place to store all web references in no particular order etc... More to come....


Wednesday, February 16, 2011

Using MEF to expose interfaces in your Silverlight Mvvm Apps

Great article on building composable applications in MEF and using the MVVM pattern.

Using MEF to expose interfaces in your Silverlight MVVM Applications.

Technical Debt

I re-read this article the other day, its still absolutely current describes the common problem of "Technical Debt".



TFS Source Control Resources

Source of information:






Team Foundation Server Permissions


You can control access to the team projects and team project collections in your deployment of Visual Studio Team Foundation Server by understanding and configuring the permissions that are assigned to the users and groups in that deployment. 
Permissions determine the authorization for user actions such as workspace administration and project creation. When you create a project in Team Foundation Server, four default groups are created for that project regardless of your choice of process template. By default, each of these groups has a set of permissions that are defined for them and that govern what members of those groups are authorized to do.
  • Project Administrators
  • Contributors
  • Readers
  • Builders
In addition to the default groups that are created for each team project, when you create a team project collection, seven default groups are created for that collection regardless of your choice of process template. Each of those groups also has a set of permissions that are defined for them.
  • Project Collection Administrators
  • Project Collection Service Accounts
  • Project Collection Build Administrators
  • Project Collection Build Service Accounts
  • Project Collection Valid Users
  • Collection Proxy Service Accounts
  • Project Collection Test Service Accounts
Five default groups are created at the server level when you install Team Foundation Server. Each of these groups has a set of permissions that are defined for them.
  • Team Foundation Administrators
  • Team Foundation Service Accounts
  • Team Foundation Valid Users
  • SharePoint Web Application Services
  • Work Item Only View Users
To effectively manage user membership in these default groups and to create custom groups, administrators must first understand the meaning of the permissions and the security implications for explicitly setting permissions.
Permission Settings

You can specify two explicit authorization settings for permissions in Team Foundation Server: Deny and Allow. There is also an implicit authorization that neither sets the permission to Allow nor sets the permission to Deny. This authorization is an implicit Deny setting that is referred to as Unset.

Deny

Deny denies authorization for the user or group to perform the actions that are stated in the permission description. Deny is the most powerful permission setting in Team Foundation Server. If a user belongs to a Team Foundation Server group that has a specific permission set to Deny, that user cannot perform that function, even if he or she belongs to another group that has that permission set to Allow. The only exception to this rule occurs when the user is a member of either theProject Administrators group for a project, the Project Collection Administrators group for a team project collection, or the Team Foundation Administrators group. If a user is a member of the Project Administrators group for a project, the permissions of that group override an explicit Deny for that user in a project. Similarly, if a user is a member of the Project Collection Administrators group, the permissions of that group override an explicit Deny for that user in that collection. If a user is a member of the Team Foundation Administrators group, the permissions of that group override an explicit Deny for that user in Team Foundation Server.

Allow

Allow grants authorization for the user or group to perform the actions that are stated in the permission description. Allow is the second-most powerful permission setting in Team Foundation Server and is set most frequently. If you do not explicitly set a permission to Allow, a user or group cannot perform that action in Team Foundation Server.

Unset

By default, most permissions in Team Foundation Server are not set to either Deny or Allow. The permissions are left unset, which implicitly denies both users and groups authorization to perform the actions that are specified in the permission description. However, because the permission is neither explicitly set to Deny nor explicitly set to Allow, authorization for that permission can be inherited from other groups of which the user or group is a member.

Default Groups and Permissions

Whenever you create a project in Team Foundation Server, groups are created at the project level. By default, each of those groups has certain permissions assigned to them. You can add permissions to these default groups, in addition to any groups or users whom you want to add at the server, collection, or project level.

Server-Level Groups and Permissions

By default, the following groups exist at the server level when you install Team Foundation Server:
  • Server \Team Foundation Administrators   Members of this group can perform all operations for Team Foundation Server. This group should be restricted to the smallest possible number of users who need total administrative control over Team Foundation Server. By default, this group contains the Local Administrators group (BUILTIN\Administrators) for any server that hosts the application services for Team Foundation. This group also contains the members of theServer\Service Accounts group.
  • Server \Team Foundation Valid Users   Members of this group have access to Team Foundation Server. This group automatically contains all users and groups that have been added anywhere within Team Foundation Server. You cannot modify the membership of this group.

  • Server \Service Accounts   Members of this group have service-level permissions for Team Foundation Server. By default, this group contains the service account that was supplied during installation. This group should contain only service accounts and not user accounts or groups that contain user accounts. By default, this group is a member of Team Foundation Administrators.
  • Server \Work Item Only View Users   Members of this group are restricted from using the full range of features that are provided when users view projects and collections in Team Web Access. Membership in this group is appropriate for those users who do not have a client access license for your deployment of Team Foundation Server.
  • Server \SharePoint Web Application Services    Members of this group have service-level permissions for the SharePoint Web applications that are configured for use with Team Foundation Server, in addition to some service-level permissions for Team Foundation Server. This group should contain only service accounts and not user accounts or groups that contain user accounts. Unlike the Service Accounts group, this group is not a member of Team Foundation Administrators.




    Rolling Back a ChangeSet
    Using the Visual Studio command line prompt you can rollback a changeset or range of changesets from TFS

    vs_command_prompt.png
    Rollback command

    TFS_rollback.png

    Thanks to Jamie Bate for this information.

Tuesday, February 8, 2011

Accessing .NET Embedded Resources

Accessing resources of any kind is usually done once inside a helper class or other mechanism that hides away the implementation details of how the resources are accessed. Or at least thats how I usually do it. Trouble is whenever its time to remember how to access the various kinds of resources I have to strain the remembering gland. Time for a post to store the information and free up some valuable brain memory kilobytes.

Here's a screen shot of my demo application showing different ways of accessing resources.


Some images are populated using Xaml and others using standard C# mechanisms.
Here's the structure of the application, note the two different images included in the Assets folder. One is set to the newer "Resource" content-type and the other to the old "EmbeddedResource".  The image in the DifferentAssembly is also a "Resource".  (Prefer Resource to the old EmbeddedResouce).



Xaml:

<Window 
    x:Class="ResourceAccessExample.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Height="350" 
    Title="MainWindow" 
    Width="525">

    <ScrollViewer>
        <StackPanel>
            <Border 
                BorderBrush="Black" 
                BorderThickness="1" 
                Margin="10" 
                Padding="10">
                <StackPanel>
                    <Image 
                        MaxHeight="75" 
                        Source="pack://application:,,,/assets/ChessMce.png" 
                        />
                    <TextBlock Text="Pack Url into same assembly" />
                </StackPanel>
            </Border>
            <Border 
                BorderBrush="Black" 
                BorderThickness="1" 
                Margin="10" 
                Padding="10">
                <StackPanel>
                    <Image 
                        MaxHeight="75" 
                        Source="pack://application:,,,/DifferentAssembly;component/UserGroup.png" 
                        />
                    <TextBlock Text="Pack Url into different assembly" />
                </StackPanel>
            </Border>
            <Border 
                BorderBrush="Black" 
                BorderThickness="1" 
                Margin="10" 
                Padding="10">
                <StackPanel>
                    <Image 
                        MaxHeight="75" 
                        Source="assets/ChessMce.png" 
                        />
                    <TextBlock Text="Relative Url into same assembly" />
                </StackPanel>
            </Border>
            <Border 
                BorderBrush="Black" 
                BorderThickness="1" 
                Margin="10" 
                Padding="10">
                <StackPanel>
                    <Image 
                        x:Name="Image2" 
                        MaxHeight="75" 
                        />
                    <TextBlock Text="Pulled from Resource Manifest using code Application static helper ('Resource')" />
                </StackPanel>
            </Border>
            <Border 
                BorderBrush="Black" 
                BorderThickness="1" 
                Margin="10" 
                Padding="10">
                <StackPanel>
                    <Image 
                        x:Name="Image3" 
                        MaxHeight="75" 
                        />
                    <TextBlock Text="Pulled from Resource Manifest using standard .NET Resource classes ('Resource')" />
                </StackPanel>
            </Border>
            <Border 
                BorderBrush="Black" 
                BorderThickness="1" 
                Margin="10" 
                Padding="10">
                <StackPanel>
                    <Image 
                        x:Name="Image4" 
                        MaxHeight="75" 
                        />
                    <TextBlock Text="Pulled from an old EmbeddedResource using standard .NET Resource classes ('Resource')" />
                </StackPanel>
            </Border>
        </StackPanel>
    </ScrollViewer>

</Window>

And the C# Code behind that populates the last three images using standard C# coding techniques:


public partial class MainWindow
    {
        public MainWindow()
        {
            InitializeComponent();
            Loaded += OnLoaded;
        }

        private void OnLoaded(object s, RoutedEventArgs e)
        {
            // Pull using the Application object (wpf only)
            var streamResourceInfo2 = Application.GetResourceStream(new Uri("assets/ChessMce.png", UriKind.Relative));
            if (streamResourceInfo2 != null)
            {
                var image = new BitmapImage();
                image.BeginInit();
                image.StreamSource = streamResourceInfo2.Stream;
                image.EndInit();
                this.Image2.Source = image;
            }

            // Using standard .NET resource classes.
            var assem = Assembly.GetEntryAssembly();
            var resourceManager = new ResourceManager(assem.GetName().Name + ".g", assem);
            using (ResourceSet set = resourceManager.GetResourceSet(CultureInfo.CurrentCulture, true, true))
            {
                // Can loop thru them
                foreach (DictionaryEntry pair in set)
                {
                    Debug.WriteLine(pair.Key.ToString());
                }

                // Access an item directly
                var image = new BitmapImage();
                image.BeginInit();
                image.StreamSource = (Stream)set.GetObject("assets/ChessMce.png", true);
                image.EndInit();
                this.Image3.Source = image;
            }

            // Using an old Embedded Resource
            // this line of code is useful to figure out the name Vs has given the resource! The name is case sensitive.
            // var names = Assembly.GetExecutingAssembly().GetManifestResourceNames();
            using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ResourceAccessExample.Assets.FreeCellMCE.png"))
            {
                var image = new BitmapImage();
                image.BeginInit();
                image.StreamSource = stream;
                image.EndInit();
                this.Image4.Source = image;
            }
        }
    }
Brain capacity recycled...