Profitbase Studio / Server and SQL Server dependencies

Profitbase Studio / Server is using parts of the SQL Server API directly, so it is required that these components are installed on the same computer as the Profitbase Studio and/or Profitbase Studio Server. Although these requirements are listed in the System Requirements document, they may from time to time (using clever ninja tactics) avoid attention from people setting up the system.

So a quick recap of the SQL Server dependencies for Profitbase Studio / Server;

When PB Studio / Server is running on the SQL Server 2005 Platform
Install SSMS 2005 OR install Microsoft SQL Server 2005 Management Objects Collection which is a part of the SQL Server 2005 Feature Pack.

When PB Studio / Server is running on the SQL Server 2008 Platform
Install SSMS 2008 OR install Microsoft SQL Server 2008 Management Objects whis is a part of the SQL Server 2008 Feature Pack.

Xml namespace simplified in Silverlight 4.0

 

A feature added to Silverlight 4 that has not received much attention is the introduced support for the XmlnsDefinition and XmlnsPrefix attributes in custom assemblies. These attributes has been supported in WPF since day one, and has finally made their way into Silverlight as well.

The XmlnsDefinitionAttribute is used for mapping one or more CLR namespaces to one or more XML namespaces. The benefit of doing so is that
1) The user does not have to think or know about the CLR namespaces or assembly names when adding xmlns imports in XAML files
2) Because you can map several CLR namepaces to a single XML namespace, you can get away with a single XML namespace in your XAML files instead of one pr. CLR namespace when referencing components in your custom assemblies.

You typically define the XmlnsDefinitionAttribute in the AssemblyInfo.cs-file like so:

[assembly: XmlnsDefinition("http://schemas.mycompany.com/silverlight","MyCompany.Windows.Controls")]
[assembly: XmlnsDefinition("http://schemas.mycompany.com/silverlight", "MyCompany.Windows.Behaviors")]

Then, in a XAML file, you can simply add an xmlns import like this;

<UserControl x:Class="SilverlightApplication2.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:myCompany="http://schemas.mycompany.com/silverlight"

and now you can access the types specified in MyCompany.Windows.Controls and MyCompany.Windows.Behaviors throught the myCompany xmlns prefix.

Further, you can use XmlnsPrefixAttribute to specify a default prefix associated with a XML namespace. This prefix is used by the Visual Studio and Blend designer when you drag/drop custom components from the toolbox onto the designer surface.

[assembly: XmlnsPrefix("http://schemas.mycompany.com/silverlight","myCompany")]
[assembly: XmlnsDefinition("http://schemas.mycompany.com/silverlight","MyCompany.Windows.Controls")]
[assembly: XmlnsDefinition("http://schemas.mycompany.com/silverlight", "MyCompany.Windows.Behaviors")]


 

 

Object-To-Object Binding / ViewModel-To-ViewModel Binding

 

There may be times when you need to pass data back and forth between ViewModels in a loosly coupled way, without having to handle this in your ViewModels or code behind. Consider a parent-child ViewModel scenario, where your parent ViewModel may contain data resulting in the creation of multiple child ViewModels, for example the case when your parent ViewModel has a collection of business objects, and you need to enable editing each business object separately unsing their own View-ViewModels.

The XAML code below has an ItemsControl which binds to the Items collection of the ViewModel set as the DataContext of the parent View.
This will create an instance of the ChildView for each member of the Items collection.

<
ItemsControlItemsSource="{BindingPath=Items}"HorizontalAlignment="Center"VerticalAlignment="Center">
            <
ItemsControl.ItemTemplate>
                <
DataTemplate>
                   
<local:ChildView>
                  
</local:ChildView>
                </DataTemplate>
            </
ItemsControl.ItemTemplate>
        </
ItemsControl>

What we would like, is to pass each item in the Items collection to the ViewModel of each created ChildView so that an action can be taken based on that information.
In order to do this, we can create a binding which binds to a property of the ChildView ViewModel, and one binding that binds to the item from the parent ViewModel Items collection. Then, we need to tie those tow bindings together so that when one of the bound items changes, the other one gets updated as well.

A solution to this may look like this;

<ItemsControl ItemsSource="{Binding Path=Items}" HorizontalAlignment="Center" VerticalAlignment="Center">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <TextBlock Text="{Binding}" Visibility="Collapsed" x:Name="HiddenTextBlock"/>
                        <local:ChildView>
                            <local:BindingBehaviors.ObjectToObjectBinding>
                                <local:ObjectToObjectBinding Source="{Binding Path=Text, ElementName=HiddenTextBlock}" Target="{Binding Path=MyProperty, Mode=TwoWay}"/>
                            </local:BindingBehaviors.ObjectToObjectBinding>
                        </local:ChildView>
                    </Grid>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

What we have done here is to create a binding behavior that ties a Source and Target binding together so that when the Source changes, the Target (MyProperty) gets updated as well. For this example to work, we needed to do a little “hack” by defining the Source binding to bind to a TextBlock which holds on to a member of the Items collection from the parent ViewModel (as the Items collection in this case happens to contain strings. If you need to store an Object, change the TextBlock to a ContentPresenter, for example, and bind to the Content property instead). The Target binding defines a binding to the MyProperty property of the ChildView ViewModel, so that MyProperty will get the value of the item from the Items collection when the ChildView is loaded.

Besides the BindingBehavior class that defines the ObjectToObjectBinding attached property, we need a class for our Source and Target bindings, and also a class that handles / relays the data updates between the Source and Target.

To hold on to our Source and Target bindings, we need a simple ObjectToObjectBinding class with only two properties;

public class ObjectToObjectBinding
    {
        public Binding Source { get; set; }
        public Binding Target { get; set; }
    }

The class that handles exchanging data between the Source and Target is also as simple as it gets; All it does is copy the value of the Source property to the value of the Target propery, and vica verca, when a change occurs.

public class DataRelay : DependencyObject
    {
        #region Source

        public static readonly DependencyProperty SourceProperty =
            DependencyProperty.Register("Source", typeof(object), typeof(DataRelay),
                new PropertyMetadata(null, new PropertyChangedCallback(OnSourceChanged)));

        public object Source
        {
            get { return (object)GetValue(SourceProperty); }
            set { SetValue(SourceProperty, value); }
        }

        private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((DataRelay)d).OnSourceChanged(e);
        }

        protected virtual void OnSourceChanged(DependencyPropertyChangedEventArgs e)
        {
            this.Target = e.NewValue;
        }

        #endregion

        #region Target

        public static readonly DependencyProperty TargetProperty =
            DependencyProperty.Register("Target", typeof(object), typeof(DataRelay),
                new PropertyMetadata(null, new PropertyChangedCallback(OnTargetChanged)));

        public object Target
        {
            get { return (object)GetValue(TargetProperty); }
            set { SetValue(TargetProperty, value); }
        }

        private static void OnTargetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((DataRelay)d).OnTargetChanged(e);
        }

        protected virtual void OnTargetChanged(DependencyPropertyChangedEventArgs e)
        {
            this.Source = e.NewValue;
        }

        #endregion
    }


The code needed to tie the two bindings together is pretty simple;

private static void OnObjectToObjectBindingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ObjectToObjectBinding binding = e.NewValue as ObjectToObjectBinding;
            if (binding != null)
            {
                if (binding.Source == null)
                    throw new ArgumentNullException("binding.Source");
                if (binding.Target == null)
                    throw new ArgumentNullException("binding.Target");

                DataRelay dataRelay = new DataRelay();

                BindingBehaviors.SetObjectToObjectBindingRelay(d, dataRelay);

                BindingOperations.SetBinding(dataRelay, DataRelay.SourceProperty, binding.Source);
                BindingOperations.SetBinding(dataRelay, DataRelay.TargetProperty, binding.Target);
            }
        }

What we have done here, is created a private attached property called ‘ObjectToObjectBindingRelay’ which allows us to attach an instance of the DataRelay object to a DependencyObject (in this case, our ChildView).

Next, we sets the Source binding to update DataRelay Source property, and the Target binding to update the Target property, so that data is exchanged between the source and target object when data changes.

Download source code

Using Bindings in Styles in Silverlight

 

One of the differences between WPF and Silverlight is that using Bindings when setting properties in styles is still not supported (SL 4). If you try to do so, your application will simply crash.
In WPF, you can do something like this;

<Style TargetType="{x:Type ListBoxItem}">
       <Setter Property="Background" Value="{Binding Path=MyColor}"/>
</Style>

Although not directly supported, you can achieve the same thing in Silverlight using attached properties. The workaround is to specify an Attached Property in the Setter Property, and then use a “proxy” in the Setter Value to set up the binding between the actual property of the UI element and the object from the data binding. This technique can also be used for things like wiring up command to react to user input, for example when a user double clicks a ListBoxItem.



The following example shows how to set the background color of a ListBoxItem through data binding, and also how to react to a double click on the item.

<ListBox x:Name="listBox1">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Path=Name}"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
            <ListBox.ItemContainerStyle>
                <Style TargetType="ListBoxItem">
                    <Setter Property="b:BindingBehavior.PropertyBinding">
                        <Setter.Value>
                            <b:PropertyBinding Binding="{Binding Path=BackgroundBrush}" Property="Background"/>
                        </Setter.Value>
                    </Setter>
                    <Setter Property="b:BindingBehavior.DoubleClickCommandBinding">
                        <Setter.Value>
                            <b:CommandBinding Command="{Binding Path=DataContext.TestCommand, ElementName=LayoutRoot}"
                                              CommandParameter="{Binding}"/>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ListBox.ItemContainerStyle>
        </ListBox>

As you can see, both the Setter Properties have Attached Properties defined instead of the actual property names of the ListBoxItem. In the Setter Values, I have added my proxy classes where I have specified the bindings and the name of the ListBoxItem property I want a binding to apply to.

The BindingProperty proxy class is very simple and contains only two properties; one for holding the name of the property you want to bind to and one for the binding itself.

public class PropertyBinding
    {
        public Binding Binding { get; set; }
        public string Property { get; set; }
    }

The BindingBehavior class is responsible for creating the actual binding based on an instance of the PropertyBinding. It does so using reflection on the ListBoxItem to locate the dependency property specified in the Property attribute of the PropertyBinding proxy instance.

private static void OnPropertyBindingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            FrameworkElement frameworkElement = d as FrameworkElement;
            if (frameworkElement == null)
            {
                throw new ArgumentException("The PropertyBinding behavior can only be applied to FrameworkElement types");
            }

            PropertyBinding styleBinding = e.NewValue as PropertyBinding;
            if (styleBinding != null)
            {
                string depPropName = string.Concat(styleBinding.Property, "Property");
                if (depPropName.IndexOf('.') > -1)
                {
                    int index = depPropName.LastIndexOf('.');
                    depPropName = depPropName.Substring(index);
                }
                FieldInfo dependencyPropertyField = frameworkElement.GetType().GetField(depPropName, BindingFlags.Public
                    | BindingFlags.Static
                    | BindingFlags.FlattenHierarchy);
                if (dependencyPropertyField != null)
                {
                    DependencyProperty dependencyProperty = dependencyPropertyField.GetValue(null) as DependencyProperty;
                    if (dependencyProperty != null)
                    {
                        frameworkElement.SetBinding(dependencyProperty, styleBinding.Binding);
                    }
                }
            }

        }
For the command binding, a similar approach is used. The CommandBinding proxy class contains a Binding property for setting the Command and CommandParameter, and then the BindingBehavior class creates the actual binding in the OnXXXChanged event handler.

public class CommandBinding
    {
        public Binding Command { get; set; }
        public Binding CommandParameter { get; set; }
    }
private static void OnDoubleClickCommandBindingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            FrameworkElement element = d as FrameworkElement;
            if (element == null)
            {
                throw new InvalidOperationException("This behavior can only be applied to FrameworkElement types");
            }

            CommandBinding styleBinding = e.NewValue as CommandBinding;
            if (styleBinding != null)
            {
                element.SetBinding(BindingBehavior.DoubleClickProperty, styleBinding.Command);
                if (styleBinding.CommandParameter != null)
                {
                    element.SetBinding(BindingBehavior.DoubleClickParameterProperty, styleBinding.CommandParameter);
                }
                else
                {
                    element.ClearValue(BindingBehavior.DoubleClickParameterProperty);
                }
            }
            else
            {
                element.ClearValue(BindingBehavior.DoubleClickProperty);
                element.ClearValue(BindingBehavior.DoubleClickParameterProperty);
            }
        }

 

The source code can be downloaded from here. (VS 2010 Solution)

Extracting MSI files from the installer .exe

Profitbase software is normally installed by running an installer .exe-file. The .exe-files act as bootstrappers for reading the content of the .MSI-file, checking if the required version of the Windows Installer is installed on the system, and then launches the .MSI that takes care of the actual installation of the product.

If for example you want to install the product using Group Policy deployment, you need to extract the .MSI from the .EXE. A way to do this is using the UniversalExtractor tool. This tool extracts the .MSI-file (along with other files as well) from the .EXE-file to a folder of your choice.
Once the .MSI-file is extracted, you can run it directly or use the Windows Installer tool (MSIEXEC.exe) from the command prompt to do additional actions. To get a list of your options with the Windows Installer tool, simply open a command prompt and type “MSIEXEC”

Building a claims aware ASP.NET web application

 

This post is a follow up to my previous post about Building a claims aware WCF Service using Windows Identity Foundation. This time, I’ll lay out the steps needed to secure access to a ASP.NET web application using Windows Identity Foundation.

1) Go to the STS application and add the following code to Default.aspx:

protected void Page_PreRender(object sender, EventArgs e)
        {
            string action = Request.QueryString[WSFederationConstants.Parameters.Action];

            try
            {
                if (action == WSFederationConstants.Actions.SignIn)
                {
                    // Process signin request.
                    SignInRequestMessage requestMessage = (SignInRequestMessage)WSFederationMessage.CreateFromUri(Request.Url);
                    if (User != null && User.Identity != null && User.Identity.IsAuthenticated)
                    {
                        SecurityTokenService sts = new AppSecurityTokenService(AppSecurityTokenServiceConfiguration.Current);
                        SignInResponseMessage responseMessage = FederatedPassiveSecurityTokenServiceOperations.ProcessSignInRequest(requestMessage, User, sts);
                        FederatedPassiveSecurityTokenServiceOperations.ProcessSignInResponse(responseMessage, Response);
                    }
                    else
                    {
                        throw new UnauthorizedAccessException();
                    }
                }
                else if (action == WSFederationConstants.Actions.SignOut)
                {
                    // Process signout request.
                    SignOutRequestMessage requestMessage = (SignOutRequestMessage)WSFederationMessage.CreateFromUri(Request.Url);
                    FederatedPassiveSecurityTokenServiceOperations.ProcessSignOutRequest(requestMessage, User, requestMessage.Reply, Response);
                }
                else
                {
                    throw new InvalidOperationException(
                        String.Format(CultureInfo.InvariantCulture,
                                       "The action '{0}' (Request.QueryString['{1}']) is unexpected. Expected actions are: '{2}' or '{3}'.",
                                       String.IsNullOrEmpty(action) ? "<EMPTY>" : action,
                                       WSFederationConstants.Parameters.Action,
                                       WSFederationConstants.Actions.SignIn,
                                       WSFederationConstants.Actions.SignOut));
                }
            }
            catch (Exception exception)
            {
                throw new Exception("An unexpected error occurred when processing the request. See inner exception for details.", exception);
            }
        }

This is just a copy of the boliler plate code that is auto generated by Visual Studio when you create an ASP.NET Security Token Service Web Site.

The two most interesting method calls in the above code is the call to FederatedPassiveSecurityTokenServiceOperations.ProcessSignInRequest(…) and FederatedPassiveSecurityTokenServiceOperations.ProcessSignInResponse(..).

What ProcessSignInRequest(..) does is creating a RST (RequestSecurityToken) based on the requestMessage and a ClaimsPrincipal based on the IPrincipal passed in. It then calls the SecurityTokenService.Issue(…) method passing in the RST and the ClaimsPrincipal and returns a SignInResponseMessage based on the RSTR (RequestSecurityTokenResponse) returned by the SecurityTokenService.Issue method.

ProcessSignInResponse(…) simply writes the content of the the SignInResponseMessage to the HttpResponse output stream.

2) Add a Login.aspx page with a single button. In the button click event, add the following code to simulate a successful login

void buttonLogin_Click(object sender, EventArgs e)
       {
           if (Request.QueryString["ReturnUrl"] != null)
           {
               FormsAuthentication.RedirectFromLoginPage("Tore Senneseth", false);
           }
           else
           {
               FormsAuthentication.SetAuthCookie("Tore Senneseth", false);
               Response.Redirect("default.aspx");
           }

       }

 

3) Open the web.config file and change the authentication from Windows to Forms and deny all unauthenticated users access.

<authentication mode="Forms">
      <forms loginUrl="Login.aspx" protection="All" timeout="30" name=".ASPXAUTH" path="/"
             requireSSL="false" slidingExpiration="true" defaultUrl="default.aspx"
             cookieless="UseDeviceProfile" enableCrossAppRedirects="false"/>
    </authentication>
    <!-- Deny Anonymous users. -->
    <authorization>
      <deny users="?"/>
    </authorization>

4) Switch back to the main web application, SecureWebApplication. (Where our claims aware WCF Service is implemented) and open the web.config-file

Change authentication from Windows to None and deny anonymous access.

<authentication mode="None"/>
    <authorization>
      <deny users="?"/>
    </authorization>

6) Add Windows Identity Foundation httpModules to configuration/system.web/httpModules

<httpModules>
      <add name="ClaimsPrincipalHttpModule"
           type="Microsoft.IdentityModel.Web.ClaimsPrincipalHttpModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      <add name="WSFederationAuthenticationModule"
           type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      <add name="SessionAuthenticationModule"
           type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    </httpModules>

7) Add Windows Identity Foundation modules to configuration/system.webServer/modules

<modules>
      <add name="ClaimsPrincipalHttpModule"
           type="Microsoft.IdentityModel.Web.ClaimsPrincipalHttpModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
           preCondition="managedHandler"/>
      <add name="WSFederationAuthenticationModule"
           type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
           preCondition="managedHandler"/>
      <add name="SessionAuthenticationModule"
           type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
           preCondition="managedHandler"/>
    </modules>

We’ve added 3 modules, ClaimsPrincipalHttpModule, SessionAuthenticationModule and WSFederationAuthenticationModule.

What does all of these modules do? For a good explaination, take a look at this blog post by Dominic Baier. Also, you’ll find a detailed explaination about the WSFederationAuthenticationModule in the MSDN documentation here.

8 ) Modify the microsoft.identityModel/service/ element by adding a serviceCertificate element. Here, we’ll need to specify the certificate used by the STS to encrypt the security token so that the Relying party (our web site) is able to decrypt the security token once it is received. In the attached sample project, the certificate being used has the subject name STSTestCert.

<service>
      <serviceCertificate>
        <certificateReference findValue="0E2A9EB75F1AFC321790407FA4B130E0E4E223E2" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint"/>
      </serviceCertificate>
    </service>

9) Add the uri of your application to the audienceUris element. 

<audienceUris>
        <add value="http://localhost:25546"/>
        <add value="http://localhost:25546/MyService.svc"/>
      </audienceUris>

The audienceUris section specifies a list of valid audience URIs for incoming SAML tokens. 
When the client sends an RST (RequestSecurityToken) to the STS, it usually includes an AppliesTo setting that indicates who the token should be issued to. If present, the STS will use this information to populate the SAML token audience uri setting. When the client receives the issued SAML token, the audience URI setting in the SAML token must match one of the audience URIs specified in the audienceUris list. If the audience Uri setting in the SAML token is not present in the audienceUris list, the token is refused. If you want to disable this behavior, you can set the mode property to “Never”, <audienceUris mode=”Never”/>.

10) To verify that your site is working, set the relying party (SecureWebSite), as the startup project of the solution and Default.aspx as start page, add an asp:Label to Default.aspx and add the following code to the Page_Load event handler.

this.labelUserName.Text = ((IClaimsPrincipal)Thread.CurrentPrincipal).Identity.Name;

Building a claims aware WCF Service using Windows Identity Foundation

Windows Identity Foundation (WIF) just shipped, so I decided to give it a go and see how easy it was to get started.
There’s an easy way to get started building an STS and claims aware WCF service, and there’s a hard way. The easy way is to just use the templates provided by Visual Studio. The hard way is to do everything manually. I decided to do it the hard way because of two reasons;
1: I wanted to learn the details, and 2: If I could get it working, I would WIF-enable existing projects (in my case, Silverlight projects).

So here’s the steps I went through in order to get a my basic claims aware WCF up and running:

1) In Visual Studio, create a new Web Application, let’s call it SecureWebApplication

2) Create an STS application (Security Token Service) by adding a new web application to the solution. Let’s call it SecureWebApplication_STS

3) Add a reference to Microsoft.IdentityModel.dll, System.IdentityModel.dll and System.ServiceModel.dll to the STS application.
Note! You may need to set Copy Local = true for Microsoft.IdentityModel.dll before the STS app can be called.

4) In the STS application, add the following classes: Common, AppSecurityTokenService, CertificateUtil and AppSecurityTokenServiceConfiguration. (Get implementation of classes from the web site you get when creating an ASP.NET Security Token Service Web Site. File -> New -> Web Site…).

5) Add a new text file to the STS application. Call it AppSTS.svc.

6) Edit AppSTS.svc so it contains the following line;

<%@ ServiceHost Language="C#"
                Debug="true"
                Factory="Microsoft.IdentityModel.Protocols.WSTrust.WSTrustServiceHostFactory"
                Service="SecureWebApplication_STS.AppSecurityTokenServiceConfiguration"  %>


This will enable our STS to be hosted by a service host in our web application.

7) In the STS application, edit the web.config file and add configuration settings that specifies how the STS should encrypt and sign issued security tokens;

<appSettings>
    <add key="IssuerName" value="SigninSTS"/>
    <add key="SigningCertificateName" value="CN=STSTestCert"/>
    <add key="EncryptingCertificateName" value="CN=STSTestCert"/>
  </appSettings>


Note! The STSTestCert is a X509Certificate installed as part of the Windows Identity Foundation SDK. Feel free to use a different certificate, but this walkthrough assumes that STSTestCert is used.

8 ) In the STS application, edit the web.config file and add the WCF service configuration for the STS service. 

<system.serviceModel>
    <services>
      <service name="Microsoft.IdentityModel.Protocols.WSTrust.WSTrustServiceContract"
               behaviorConfiguration="ServiceBehavior">
        <endpoint address="IWSTrust13" binding="ws2007HttpBinding"
                  contract="Microsoft.IdentityModel.Protocols.WSTrust.IWSTrust13SyncContract"
                  bindingConfiguration="ws2007HttpBindingConfiguration"/>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:14499/AppSTS.svc"/>
          </baseAddresses>
        </host>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <bindings>
      <ws2007HttpBinding>
        <binding name="ws2007HttpBindingConfiguration">
          <security mode="Message">
            <message establishSecurityContext="false"/>
          </security>
        </binding>
      </ws2007HttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>


9) We should now have a working STS that can be used by WCF Services. Let’s go back to your main web application and add a claims aware WCF Service.

10) Go to the main web application, SecureWebApplication, and add a reference to Microsoft.IdentityModel.dll and System.ServiceModel.dll.

Note! You may need to set Copy Local = true property for Microsoft.IdentityModel.dll before executing the app.

11) Add a Silverlight-enabled WCF Service, or just a plain WCF Service. I’ll be using a SL-enabled WCF Service in this walkthrough. Lets call the service MyService.scv.

12) Once you have added the WCF service, open the web.config-file

13) In the web.config-file, remove the default customBinding configuration added by Visual Studio and specify the service to use ws2007FederationHttpBinding instead.

Optionally, you can remove the <serviceHostingEnvironment aspNetCompatibilityEnabled=”True” /> element.

<services>
      <service behaviorConfiguration="SecureWebApplication.MyServiceBehavior"
               name="SecureWebApplication.MyService">
        <endpoint address="" binding="ws2007FederationHttpBinding"
                  bindingConfiguration="MyServiceBindingConfiguration"
                  contract="SecureWebApplication.MyService"/>
        <endpoint address="mex" binding="mexHttpBinding"
                  contract="IMetadataExchange"/>
      </service>
 </services>


14) Before we can configure the service behavior, we need to register a WCF extension for Windows Identity Foundation which allows federation.

In system.serviceModel, add an the following section

<extensions>
      <behaviorExtensions>
        <!-- This behavior extension will enable the service host to be Claims aware -->
        <add name="federatedServiceHostConfiguration"
             type="Microsoft.IdentityModel.Configuration.ConfigureServiceHostBehaviorExtensionElement, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      </behaviorExtensions>
 </extensions>


15) Now we’re ready to define the service behavior. Add the following behavior to system.serviceModel/behaviors/serviceBehaviors. The service certificate we specify in the behavior is the certificate used by the STS to encrypt the security token (the certificate configured in step 7)

<behavior name="SecureWebApplication.MyServiceBehavior">
          <federatedServiceHostConfiguration/>
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <serviceCredentials>
            <serviceCertificate findValue="0E2A9EB75F1AFC321790407FA4B130E0E4E223E2"
                                storeLocation="LocalMachine" storeName="My"
                                x509FindType="FindByThumbprint"/>
          </serviceCredentials>
 </behavior>


16) Finally, we need to configure our ws2007FederationBinding, which is the binding used by out STS.

Add the following binding to system.serviceModel/bindings

<ws2007FederationHttpBinding>
        <binding name="MyServiceBindingConfiguration">
          <security mode="Message">
            <message>
              <issuerMetadata address="http://localhost:14499/AppSTS.svc/mex" />
            </message>
          </security>
        </binding>
      </ws2007FederationHttpBinding>


17) Our next steps involves configuring our WCF Service to use Windows Identity Foundation, so we’ll just stay in the web.config-file.

18) The first step is to register a new WIF config section so that we can specify our WIF configuration in the web.config-file. Add the following line to configuration/configSections in the web.config-file

<section name="microsoft.identityModel"
             type="Microsoft.IdentityModel.Configuration.MicrosoftIdentityModelSection, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>


19) Now we’re ready to WIF-enable our WCF service. We do that by specifying the content of the microsoft.identityModel section as follows:

<microsoft.identityModel>
  <service>
    <audienceUris>
      <add value="http://localhost:14488/MyService.svc"/>
    </audienceUris>
    <federatedAuthentication>
      <wsFederation passiveRedirectEnabled="true" issuer="http://localhost:14499" realm="http://localhost:14488" requireHttps="false"/>
      <cookieHandler requireSsl="false"/>
    </federatedAuthentication>
    <issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
      <trustedIssuers>
        <add thumbprint="0E2A9EB75F1AFC321790407FA4B130E0E4E223E2" name="http://localhost:14499"/>
      </trustedIssuers>
    </issuerNameRegistry>
  </service>
</microsoft.identityModel>


20) We now have a working claims aware WCF Service. To test it, you can create a new test web application in the same solution and add a service reference to the service.

Activity Start Interval in the Parallel Activity

A Data Flow Parallel Activity has a setting called “Activity Start Interval”. Activity Start Interval specifies the time in seconds elapsed between the start of each activity. For example, if the value is 0.2, the activities will start at a 0.2 seconds interval. The reason you’d want to use this setting is that on some systems, you may experience connection pool problems when the activities are started to rapidly. As a result, the Data Flow activities will fail to start and you will get the following error message in the log.
Timeout expired.  The timeout period elapsed prior to obtaining a connection from the pool.  This may have occurred because all pooled connections were in use and max pool size was reached.

Setting the Activity Start Interval to a higher value will fix this problem.

WCF Routing Service and custom filters

WCF 4 now has a built-in way for routing WCF service calls, the System.ServiceModel.Routing.RoutingService, found in System.ServiceModel.Routing.dll. There are several reasons you may want to use routing, for example exposing just a single endpoint even though you have several services or routing messages throught multiple routers within a system.
The routing is done using message filters. Message filters are added to routing tables and specifies the endoints that the RoutingService should route messages to when the message filter condition is matched.

In this post, I’ll show an example of using custom message filters in order to route messages to two WCF services from a Silverlight application using the RoutingService.

1) Create a new Silverlight application and host it in a web site. Lets call it ServiceRouting.
2) Add a new Silverlight-enabled WCF Service to the web site, lets cal it DataService.svc
3) Open DataService.svc and set the Namespace property of the the ServiceContract attribute to some url, for example like this: 

[ServiceContract(Namespace = "http://services.company.com/myapp/processingservice")]

Note that setting the Namespace does not have anything to do with routing directly, but in this exaple I’ll be using Namespace in my custom filter to do the routing

4) Add a reference to System.ServiceModel.Routing.dll and add a routing service to your web site. To do this, simply add a new text file and call it RouterService.svc

Edit RouterService.svc so tha it looks like this.

<%@ ServiceHost Language="C#" Debug="true" Service="System.ServiceModel.Routing.RoutingService,
     System.ServiceModel.Routing, version=4.0.0.0, Culture=neutral,
     PublicKeyToken=31bf3856ad364e35" Factory="ServiceRouting.RoutingServiceHostFactory, ServiceRouting" %>

Note that I have specified a Factory. I’m using .NET 4.0 Beta 2 which requires using a service factory to add the

AspNetCompatibilityRequiremts attribute. The RoutingService in the release version of .NET 4 should contains that attrbute by default: Here is the factory class used to add the AspNetCompatibilityRequirements attribute. Add this class to your web site project.

public class RoutingServiceHostFactory : ServiceHostFactory
    {
        protected override System.ServiceModel.ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
        {
            ServiceHost host = base.CreateServiceHost(serviceType, baseAddresses);
            AspNetCompatibilityRequirementsAttribute attrib = host.Description.Behaviors.Find<AspNetCompatibilityRequirementsAttribute>();
            if (attrib == null)
            {
                attrib = new AspNetCompatibilityRequirementsAttribute();
                host.Description.Behaviors.Add(attrib);
            }
            attrib.RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed;
            return host;
        }
    }

5) Next, we need to configure the routing service so that it can route messages to our Data Service.This is done in web.config.

a) Add the service configuration for the routing service

<services>
  <service behaviorConfiguration="routingServiceBehavior" name="System.ServiceModel.Routing.RoutingService">
    <endpoint address="" binding="basicHttpBinding" name="reqReplyEndpoint"
      contract="System.ServiceModel.Routing.IRequestReplyRouter" />
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:42001/RouterService.svc" />
      </baseAddresses>
    </host>
  </service>
</services>


b) Add a service behavior for the routing service. The important part here is the routing element which specifies the routing table.

<behaviors>
  <serviceBehaviors>
    <behavior name="routingServiceBehavior">
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true"/>
      <routing filterTableName="routingTable"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

c) Add the routing table and message filters. These are the settings used by the router service to do the actual routing of the messages.

This is also the section where you specify your custom filter.

<system.serviceModel>
  <routing>
    <filterTables>
      <filterTable name="routingTable">
        <add filterName="dataServiceFilter" endpointName="DataServiceClient"/>
      </filterTable>
    </filterTables>
    <filters>
      <filter name="dataServiceFilter"
              filterType="Custom"
              customType="ServiceRouting.CustomMessageFilter, ServiceRouting"
              filterData="http://services.company.com/myapp/dataservice"/>
    </filters>
  </routing>
</system.serviceModel>

d) Finally, we need to specify the endpoint to call when a message passes the message filter.

<system.serviceModel>
  <client>
    <endpoint name="DataServiceClient"
              address="http://localhost:42001/DataService.svc"
              binding="basicHttpBinding"
              contract="*"/>
  </client>
</system.serviceModel>
Note! I have also changed the DataService configuration so that basicHttpBinding is used instead of the defaultcustomBinding.
<service name="ServiceRouting.DataService">
        <endpoint address="" binding="basicHttpBinding" contract="ServiceRouting.DataService" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>

 

So now that we have our config and services in place, all we need to do is create the custom filter. To create a custom filter, you need to create a class that inherits from MessageFilter and has a constructor taking a string.

public class CustomMessageFilter : MessageFilter
    {
        private string _matchData;
        public CustomMessageFilter(string matchData)
        {
            this._matchData = matchData;
        }        

        public override bool Match(System.ServiceModel.Channels.Message message)
        {
            return message.Headers.Action.IndexOf(this._matchData) > -1;
        }

        public override bool Match(System.ServiceModel.Channels.MessageBuffer buffer)
        {
            throw new NotImplementedException();
        }
    }

The value specified in the filterData attribute is passed to CustomMessageFilter at creation time. The value can then be used to evaluate whether a message should pass the filter.

If there is a match, the DataServiceClient endpoint will be called.

To test the routing service, go to the Silverlight application and add a service reference to the DataService. Then in ServiceReferences.ClientConfig,  change the address to point to the routing service, http://localhost:42001/RouterService.svc.

Posted in WCF