Thursday, November 17, 2011

MSIS7042: The same client browser session has made 'X' requests in the last 'Y' seconds.

This exception has been written to the ADFS event log after unsusccessful sign-in of one of our Relying Party applications. From the user perspective, the control flow seems correct, the application redirects to the ADFS login page but then rather than signing in, it forces the browser to go to ADFS again and again. After few frantic redirects within the browser, ADFS shows the exception message.

It turned out that there is a simple cause of such unindented behaviour – the FederatedPassiveSignIn control on the RP’s login page has the AutoSignIn property set to true.

When the browser hits the page, it unconditionally redirects to ADFS and then, upon returning when something is wrong, it redirects to ADFS again. Problem is that the ADFS shows the login page only once and then it automatically redirects back to the application because user is already authenticated. This causes the “redirection loop” within the browser as the application and ADFS start to unconditionally redirect between each other.

If this is the case in your scenario (AutoSignIn==”true”), then there’s a simple workaround. All you have to do is to provide a SignInError handler for the control where you had to turn off the auto signing:

FederatedPassiveSignIn1.SignInError +=
    ( s, e ) =>
    {
        // turn off auto signing to prevent the "redirection loop"
        FederatedPassiveSignIn1.AutoSignIn = false;
        // optionally show the error message 
        lblError.Text = e.Exception.Message;
    };

In our case it turned out that the reason for the error in the authentication pipeline was caused by wrong STS certificate thumbprint at the RP-side which caused WIF to throw a security exception from the IssuerNameRegistry.

Tuesday, November 15, 2011

Easy Unity Application Block integration in .NET applications

Unity Application Block is a lightweight dependency injection container from Microsoft Patterns & Practices. This article is intended to show how quickly and easily integrate Unity with your code.

Start by downloading and installing Unity. The current version, 2.1, consist of 5 libraries:

  • Microsoft.Practices.ServiceLocation.dll
  • Microsoft.Pracitces.Unity.dll
  • Microsoft.Practices.Unity.Configuration.dll
  • Microsoft.Practices.Unity.Interception.dll
  • Microsoft.Practices.Unity.Interception.Configuration.dll

There are at least two ways to define type bindings in Unity – declaratively in a *.xml file and programmatically in a C# code.

The nice thing is that you can combine both approaches in desired order so for example you first create few mappings programmatically and then load the static configuration which can possibly override some of mappings.

Now create a new application (Windows or web) and add references to unity libraries (first 3 will do as this tutorial doesn’t cover interceptions).

Anyway, first go to the application *.config file (app.config for Windows applications, web.config for web apps) and inform the runtime that you are going to configure unity using the *.xml file:

<?xml version="1.0"?>
<configuration>
    <configSections>
        <section name="unity" 
         type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, 
               Microsoft.Practices.Unity.Configuration"/>
    </configSections>
    <unity configSource="Configuration\unity.config"/>
</configuration>

As you can see I am delegating the Unity configuration to a separate file, Configuration\unity.config. This is a good practice as you have all the IoC configuration in a single place which doesn’t interfere with any other application settings.

For this tutorial, create a service specification and two implementations:

public interface ICustomService
{
    string BusinessOperation();
}
 
public class CustomServiceImpl : ICustomService
{
    #region ICustomService Members
 
    public string BusinessOperation()
    {
        return "foo";
    }
 
    #endregion
}
 
public class CustomServiceImpl2 : ICustomService
{
    #region ICustomService Members
 
    public string BusinessOperation()
    {
        return "bar";
    }
 
    #endregion
}

We are going to provide a static mapping in the *.xml file, Configuraton\unity.config:

<?xml version="1.0" encoding="utf-8" ?>
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <container>
        <register type="ConsoleApplication30.Logic.ICustomService, ConsoleApplication30"
                  mapTo="ConsoleApplication30.Logic.CustomServiceImpl, ConsoleApplication30" />
    </container>
</unity>

As you can see, the interface ICustomService is mapped to CustomServiceImpl.

The remaining part is to configure the service locator:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using Microsoft.Practices.ServiceLocation;
using ConsoleApplication30.Logic;
 
namespace ConsoleApplication30
{
    class Program
    {
        static void Main( string[] args )
        {
            UnityServiceLocator locator = new UnityServiceLocator( CreateConfiguredUnityContainer() );
            ServiceLocator.SetLocatorProvider( () => locator );
 
 
        }
 
        private static IUnityContainer CreateConfiguredUnityContainer()
        {
            IUnityContainer container = new UnityContainer();
 
            // (optional) provide default mappings programmatically
            container.RegisterType<ICustomService, CustomServiceImpl2>();
 
            // (optional) load static config from the *.xml file
            container.LoadConfiguration();
 
            return container;
        }
    }
}

As you can see the locator is created over a container which shows how to perform dynamic and static configuration.

Remember that Unity, as most of IoC containers, allows to reregister services – if you provide two or more mappings of the same service type to a concrete implementation, the last registered implementation is always used when you resolve the service (which is reasonable). In this tutorial I am creating a mapping in code from ICustomService to CustomServiceImpl2.

From now on you can ask the service locator services and consume them:

ICustomService service = ServiceLocator.Current.GetInstance<ICustomService>();
var foo = service.BusinessOperation();

It couldn’t be easier. Personally, when I am free to pick an IoC container, I often pick Unity – it’s reliable, simple and lightweight.

A quick quiz: in the example, I am mapping the implementation to CustomServiceImpl2 and in the next line I am loading the configuration from the *.xml file which in turn maps the implementation to CustomServiceImpl then what would be the result of resolving the service type?

Friday, November 4, 2011

Managing cookies in a WCF client

This article shows a way to manage cookies in an instance of a client proxy to a WCF service.

Background

Years ago, when we all were using the SoapHttpClientProtocol proxies, there was a property called CookieContainer. What we had to do was to create a new cookie container for the client instance and push/pull cookies from there.

Nowadays we use client proxies which derive from System.ServiceModel.ClientBase. Unfortunately, there’s no cookie container on such proxy – this is reasonable as the proxy could be used to contact a WCF Service over TCP or MSMQ where the term “http cookie” is meaningless.

Existing solutions

There are two well-known approaches to the problem, both clearly described in a blog entry by Enrico Campidoglio. First, you could take control over http headers using clumsy:

MyWebServiceClient client = new MyWebServiceClient();
 
using ( new OperationContextScope( client.InnerChannel ) )
{
    HttpRequestMessageProperty request = new HttpRequestMessageProperty();
    request.Headers["Cookie"] = "cookie header value";
 
    OperationContext.Current.OutgoingMessageProperties[
        HttpRequestMessageProperty.Name] = request;
 
    client.InvokeSomeMethod();
}

This way you can alter the way cookies are handled for a single request.

A more general approach involves writing a custom message inspector. Consult Enrico’s article for more details.

Another approach

Is it really such difficult? Is the WCF Client proxy so dumb that it cannot handle cookies on its own?

Well, it can. It seems that setting the AllowCookies property on a BasicHttpBinding to true turns on the automatic cookie management. From this moment, you can’t use any of the previously mentioned solutions because it is the client proxy to retrieve cookies and automatically append them to consecutive requests.

Wait! But you can’t append a new cookie on the client-side this way! And this was our primary requirement.

Well, you can. If you ask the server to do so.

[ServiceContract]
[ServiceBehavior(
    InstanceContextMode = InstanceContextMode.PerCall,
    ConcurrencyMode = ConcurrencyMode.Multiple,
    UseSynchronizationContext = false )]
[AspNetCompatibilityRequirements( 
   RequirementsMode = AspNetCompatibilityRequirementsMode.Required )]
 
public class TheService 
{
    // Append the cookie to the client
    [OperationContract]
    public void SetCookie( string Name, string Value )
    {
        HttpCookie cookie = new HttpCookie( Name, Value );
 
        HttpContext.Current.Response.AppendCookie( cookie );
    }
 
    // other service methods follow
}

And the client:

BasicHttpBinding binding = new BasicHttpBinding();
binding.AllowCookies = true;
 
EndpointAddress address = 
   new EndpointAddress( "http://localhost:12345/TheService.svc" );
 
TheServiceReference.TheServiceClient client = 
   new TheServiceReference.TheServiceClient( binding, address );
 
// ask the server to append the cookie
client.SetCookie( "foo", "bar" ); 

And that’s it. At the cost of one extra server request, the WCF client is able to take a full control over it’s cookies. Please add any additional methods as needed (for example to remove cookies).