Tag Archives: wcf

Writing a WS-Federation based STS using WIF

Even though SAML and WS-* have started to be looked upon as the old guard of security protocols with the popularity of OAuth 2, they are not without their merits. For one, they are inherently more secure than OAuth (in fact, you need to rely on a separate underlying secure transport for OAuth to be considered secure- and if you are someone who believes SSL is broken, then OAuth is practically insecure). It just so happens that their demerits are very visible to someone trying to implement or integrate them. OAuth, by contrast, is much simpler and easier to implement- and for most purposes, secure enough. If you have settled on WS-Federation as your protocol of choice, Windows Identity Foundation (WIF) is most likely going to be your de-facto choice. While powerful, WIF as a library is not what one would call “easy to use”. If it’s cumbersome when you use it as a relying party, the complexity is ten-fold if you try to build a security token service (STS) based on it.

I decided to take on the challenge and embarked on building a central login system (i.e. passive STS) that I could use for all of my applications. I mostly don’t like to maintain my own user database, so the central login system would then provide a hub for the user to login using any of the various identity providers out there such as Google or Facebook. The main advantage would be that the user would need to login once and be able to use all my applications. The initial plan was to make it protocol agnostic – i.e. something that will look at the incoming request, figure out what kind of request it is, and then delegate to an appropriate protocol handler. This way, the application would be able to support WS-Federation, SAML 2, OAuth 2, what-have-you, as needed. However, I saw what a great job IdentityServer has done in terms of providing a library you can easily build an OAuth based STS with – so that made me not want to pursue the OAuth path at all for this instance. My plan is to someday just build the next version of this as an OAuth STS using IdentityServer3.

With that said, if you look at the source code (available here), you will see that there is a protocol-agnostic pattern with a WS-Federation implementation. The application uses Windows Identity Foundation (WIF) as its core component. It acts as a passive STS (Security Token Service) while dividing the role of IP (Identity Provider) between the target application (or “Relying Party“) and one or more third-party providers such as Google or Facebook. The third-party providers are used for authentication, but the responsibility of storing whatever user information is needed by each application is the responsibility of that application (thus my statement that the identity provider role is divided between the Relying Party and the third-party Identity Providers). The entry point of the WS-Federation communication logic is in the WsFedLoginRequestProcessor class, specifically the ProcessSignIn method.

Each Relying Party is registered with the application through configuration – needs to have three settings populated: the realm URI (a unique identifier for the party – an example being urn:ApplicationName), the reply-to URL (the URL that this application will redirect to once the user is authenticated. This is usually the main entry point URL for the Relying Party application) and the “login service URL”. The Relying Party needs to implement a WCF service with a predefined contract (defined in ILoginService – available in the Commons Library. The service is responsible for providing information about the application as well as any given user to the STS, as well as exposing a way to create new users. The Relying Party application then needs to be configured for WIF and with the STS designated as the token issuer. There are methods available in the Commons Library that facilitate this. Communication between the Relying Party and the STS is encrypted and signed using a shared X.509 certificate.

When you navigate to a protected endpoint in the Relying Party, and are not authenticated, you are redirected to the login page hosted by the STS. This redirection request is generated by WIF and follows standard WS-Federation protocol. The STS then uses the realm information passed in the request to look up information about the party. It gets more information from the Relying Party using the ILoginService WCF endpoint. It uses this to display application-specific information in the login page. From the login page, you can use Google (using it’s OAuth API) or Facebook (using its JavaScript API) to authenticate yourself. The STS then communicates with the Relying Party using the ILoginService WCF endpoint to see if a user matching credentials just provided by Google or Facebook exists. If so, it uses this information to instruct WIF to write an encrypted session token cookie, and redirects back to the Relying Party reply-to URL – where it is now authenticated thanks to the encrypted session token cookie.

If a user is not found, the STS prompts you to enter a display name for the user that is going to be newly created. Once you provide the information, the ILoginService WCF endpoint is again used to create a new user record in the Relying Party application, and the rest of the process is same as above. When you logout from the Relying Party application, WIF sends a logout WS-Federation message to the STS which takes care of processing the logout operation.

Beware of this WCF Serialization Pitfall

Ideally, one should avoid data contracts with complex graphs- especially with repeated references and definitely ones with circular references. Those can make your payload explode on serialization. With repeated references, you may run into an integrity issue on deserialization. With circular references, the serialization will enter a recursive loop and you will probably run into a stack overflow.

Seeing that in certain situations, this becomes unavoidable, WCF has a way that you can tell it to preserve object references during serialization. You do this by setting IsReference to true on the DataContract attribute that you use to decorate the composite type that is your data contract.

So, for example:

[DataContract(IsReference = true)]
public class MyContract
{
   [DataMember]
   public string Member1 { get; set; }
   ...
   ...
}

This solves the problem- however, since WCF achieves this by augmenting the WSDL- beware of this when you are exposing your service to third parties (especially ones that are not using WCF or perhaps not .NET at all) and interoperability is a concern. Without IsReference set to true, the WSDL snippet for the above would look something like:

<xs:complexType name="MyContract">
  <xs:sequence>
    <xs:element minOccurs="0" name="Member1" nillable="true" type="xs:string"/>
    ...
  </xs:sequence>
</xs:complexType>

With IsReference set to true, this is what it looks like:

<xs:complexType name="MyContract">
  <xs:sequence>
    <xs:element minOccurs="0" name="Member1" nillable="true" type="xs:string"/>
    ...
  </xs:sequence>
  <xs:attribute ref="ser:Id"/>
  <xs:attribute ref="ser:Ref"/>
</xs:complexType>

See those two lines that got added (i.e. “Id” and “Ref”)? That could very well cause some other party’s WSDL parser/proxy generator to choke. You have been warned.

An Easy Service Proxy Executor for WCF

If you have adopted service oriented architecture (SOA) and are using WCF as the hosting/communication mechanism for your internal services, chances are you are doing one of two things: you publish each service like any old WCF service and your other services which are consumers of said published service consume it through its WSDL; or you create shared libraries that include the contract information that both the service and its consumer reference. Both are somewhat cumbersome but can be managed. If all your services are internal, though, going the WSDL route is somewhat of an unnecessary overhead and is just a bit more unmanageable.

Now, if you decide to go the second route, but still stick to the more obvious interface that WCF provides to instantiate and call proxies (ClientBase and the like), that is a bit of a waste – since those classes were built with generated-code proxies in mind. In that case, the better option really is to have a mechanism to obtain a ServiceEndpoint and use that along with the contract information to create your own ChannelFactory – where you can then call CreateChannel to get your proxy. A lot less code and a lot more manageable.

To this end, for my own purposes, I built a bunch of classes that comprise my WCF service executor module. This is part of the Services namespace in the new Commons Library. Here are what a few of the key classes look like – you should be able to surmise how they can be used. The most common usage example would be:

var response = ServiceCallerFactory
   .Create<IMyContract>()
   .Call(x => x.MyOperation(request));

 

IServiceCaller

public interface IServiceCaller<out TChannel>
{
     void Call(Action<TChannel> action);
     TResult Call<TResult>(Func<TChannel, TResult> action);
}

ServiceCaller

public class ServiceCaller<TChannel> : IServiceCaller<TChannel>
{
      private readonly ServiceEndpoint endpoint;
      private readonly EndpointAddress endpointAddress;

      public ServiceCaller() {}

      public ServiceCaller(ServiceEndpoint endpoint)
       {
             this.endpoint = endpoint;
       }

      public ServiceCaller(EndpointAddress endpointAddress)
      {
             this.endpointAddress = endpointAddress;
      }

      public void Call(Action<TChannel> action)
      {
             var channelFactory = this.endpoint != null
                   ? new ChannelFactory<TChannel>(this.endpoint)
                   : new ChannelFactory<TChannel>();

            if (this.endpointAddress != null) channelFactory.Endpoint.Address = endpointAddress;

            var channel = channelFactory.CreateChannel();
             try
             {
                   action(channel);
             }
             catch
             {
                   channelFactory.Abort();
                   throw;
             }
             finally
             {
                   channelFactory.Close();
             }
       }

      public TResult Call<TResult>(Func<TChannel, TResult> action)
      {
             var channelFactory = this.endpoint != null
                   ? new ChannelFactory<TChannel>(this.endpoint)
                   : new ChannelFactory<TChannel>();

            var channel = channelFactory.CreateChannel();
             try
             {
                   return action(channel);
             }
             catch
             {
                   channelFactory.Abort();
                   throw;
             }
             finally
             {
                   channelFactory.Close();
             }
       }
}

ServiceCallerFactory

public static class ServiceCallerFactory
{
       private static readonly object serviceCallerMapLock = new object();

      private static readonly IDictionary<Type, ServiceCaller> serviceCallerMap = new Dictionary<Type, ServiceCaller>();

      public static Func<Type, ServiceEndpoint> ServiceEndpointAccessor { get; set; }

      public static IServiceCaller<TChannel> Create<TChannel>(EndpointAddress endpointAddress = null)
      {
             ServiceCaller caller;
             if (serviceCallerMap.TryGetValue(typeof (TChannel), out caller))
                   return (IServiceCaller<TChannel>) caller;

            lock (serviceCallerMapLock)
            {
                   if (serviceCallerMap.TryGetValue(typeof (TChannel), out caller))
                         return (IServiceCaller<TChannel>) caller;

                   if (ServiceEndpointAccessor != null)
                   {
                         var serviceEndpoint = ServiceEndpointAccessor(typeof (TChannel));
                         if (endpointAddress != null) serviceEndpoint.Address = endpointAddress;
                         caller = new ServiceCaller<TChannel>(serviceEndpoint);
                   }
                   else
                   {
                         caller = endpointAddress == null
                               ? new ServiceCaller<TChannel>()
                               : new ServiceCaller<TChannel>(endpointAddress); 
                   }

                  serviceCallerMap[typeof (TChannel)] = caller;
            }

            return (IServiceCaller<TChannel>) caller;
      }
}

RudyMQ: A rudimentary message queue for Windows

To skip to the source code, click here.

For some odd reason out of the blue, I got this hankering to build a message queue (albeit rudimentary – hence the name) from scratch. I’ve been working with MSMQ for a while now, mostly as a transport for WCF. As cool as it is, it can really get on your nerves at times. It is an enterprise grade product, after all, which means there are a lot of dials you can turn. If something is not right, you’ll get an error. If your experience has been the same as mine, you will recognize the dreaded insufficient resources error that MSMQ gives you for almost any of a thousand things that can go wrong.

That got me thinking that if in most cases, I don’t really need all the enterprise grade features of MSMQ, a simpler managed-code version may suffice. .NET gives you many varieties of queue or queue-type data structures that one could leverage and combine with something like WCF to build a message queue. The only serious issues you would have to deal with, I guess, would be concurrence and performance. The use of read-write locks greatly helped with both, although I foolishly did not keep a record of the performance test results around.

Anyway, you can find more details over here. Feedback appreciated as always. You can also find the source code here.

As I think back, I think it took me longer to get the WCF binding working than the actual message queue itself. If you think just using WCF is a chore, try building your own channels. The lack of available documentation online and how to get something like this working end-to-end was shocking. So, that – I believe – is another blog post in the works.