Friday, August 23, 2013

Troubleshooting System.BadImageFormatException - Changing Target platform - A hack that might work

Introduction

Often times, we run to case where we are trying to load a dll from third party vendor that is not matching our development configuration. 
For example, we might have a .NET 4.5 solution or project that is trying to load a third party library in form of a .dll file but run into System.BadImage.FormatException error.

According to MSDN there might be any number of reason for this error. The details are listed on the following link:

But I found another solution which is not listed anywhere on MSDN and sites that I googled.

Details

Here is the scenario. I had a project that was written in .NET 4.5. I was trying to reference a library that was specific to .NET 64x platform. I added the reference to the library and complied the project. The compilation was successful. So far so good. But when I ran the application I was getting the following error:

System.BadImageFormatException
"Could not load file or assembly 'blahblah.x64, Version=x.x.xxx.xxx, Culture=neutral, PublicKeyToken=xxxxxxxxxxx' or one of its dependencies. An attempt was made to load a program with an incorrect format."

I did a lot of research and found that one reason might the mismatch in the target .NET framework. My assumption was that I might have a library that is written in .NET 2.0. 
So, the solution that I found was that I changed the target framework of my solution to .NET 2.0. I ran the application the loading of the dll worked fine. But some part of my application that were using features in .NET 4.5 stared to break. So it was a catch 22 kind of scenario. So what I did is that by pure luck I switched back my platform to 4.5 and ran the application. This time I did not get the terrible error that I mentioned above.

That seemed odd. So I created a brand new application using .NET 4.5 as framework and repeated the steps mentioned above. On adding the library for the first time and running the application, I got the error. Then I switch the framework to .NET 2.0 and rebuild the solution and ran the application and it worked. I then swithched back my solution to .NET 4.5 and this time no error. 

I do not exactly know why it starts working after switching the framework a couple of times. My guess is that when we switch framework from .NET 2.0 to .NET 4.5, I think there is a kind of upgrade that Visual Studio is doing that fixes the error.

Conclusion

If you get in similar situation where you cannot figure out the fix for the BadImageFormatException and have tried all different kinds of solution and it does not seem to work then you might try the solution that I have mentioned in the details section. That might work.



Sunday, July 28, 2013

Introduction to WCF Routing Service

A simple introduction to the world of WCF Routing




Demo code.

RoutingDemo.zip

Thursday, March 7, 2013

Enhancing Service Security Using WCF Message Inspectors

Enhancing Service Security Using WCF Message Inspectors

WCF message headers are a great source of meta data about a service and service methods. We can enhance Message headers to also include security related information.This has been an established fact.

The question comes in our minds is what are the best architecture designs to accomplish that.

In this blog we would explore the design features of such designs that makes use of Message Headers in the best optimal way.

Before we start let us take a look at standard WCF messaging architecture.


Using Message Inspectors

Message inspectors are a great way to access request messages that are going out from the client, reaching to server and the response messages that are coming out of service and heading to client.

Here is a simplified version of how that works:


As you can see from the above figure and compare that to figure about that from previous section, you will notice:
1. Message is divided into request and response messages. This essentially a more detail of actual message.
2. Messages that are coming out of client headed towards service are Request messages; and message that are coming out of service are called Response messages.
3. There are four events added that are divided into two groups. These events gives us point in time when a particular message is passed from source or reaches its destination. These events are: "BeforeSendRequest", "AfterReceiveRequest", "BeforeSendReply" and "AfterReceiveReply".

The last point mentioned above is of the utmost importance. These events are the instances where we can prepare a message that is going out from the client and interrogate a message that is coming to service to implement and ensure security.

How to implement a message inspector is beyond the scope of this post. But if you want some details, you can visit my previous post here.

Let us focus on how we can use the incoming and out going messages going through the "BeforeSendRequest", "AfterReceiveRequest", "BeforeSendReply" and "AfterReceiveReply".

Let us take look at different security implementations that use Message inspectors and Message Headers.

1. Security Token:
Using security token, we can implement a security infrastructure that is reliable, easy to maintain and yet simple enough. Following are the  main parts of such infrastructure:
  • Security token provider
  • Client
  • Message inspector
  • Message header

Here are the steps that shows how it works.
  • A client requests for security token from security token provider. 
  • A security token provider provides a token to client.
  • Client adds the acquired security token to message header before making a service request.
  • Message inspector ensures that security token is part of message headers that is sent to the service. If the message headers do not include the security token, then it throws a security exception. Otherwise it lets the message flow to service end point.
  • Once server receive the request, it reads the incoming message headers and parses out the security token. 
  • Using the parsed security token, the service then request the security token provider to authenticate security token.
  • Service executes the requested method after successful authentication.

2. Claims:
Claims provide a granular detail of what a user is authorized to. We can use the WCF message headers and message inspectors to implement an advanced security infrastructure when used with claims.  Following are the main parts of claims based solution:

  • Claims provider
  • Client
  • Message inspector
  • Message header

Here is the system flow of how the claims-based solution will work.

  • A client requests for claims to claims provider by providing its authentication details.
  • Claims provider generates a list of claims based on the user authentication level.
  • Claims provider sends the claims that user is entitled to to client.
  • Client adds the claims that it received from claims provider to message header before making a service request.
  • Message inspector on service end receives the claims that it recieved from client and generates an identity.
  • Service executes the requested method under the context of the identity that was created based on the claims.


Conclusion:

As we have seen that WCF provides all the necessary tools to a viable security infrastructure. We have discussed two architecture that can be implemented to any WCF based services. A security token based architecture is simple and can be implemented on system wide basis. This solution is best for implementations where user authentication is of utmost importance. On the other hand, Claims based implementation is more granular  complex and advanced. The complexity pays off in terms of flexibility. 





Monday, February 25, 2013

How to modify WCF message using routing service

Introduction


One of the amazing new feature of .NET 4.0 is addition of System.ServiceModel.Routing namespace (aka: routing service). Out of the box the routing service allows us to route messages from one endpoint to other endpoint(s). This is really nice in creating optimized architecture implementation. A good example of such implementation is a load-balancing application.

If you need to just do simple message routing then what you are provide out of the box is enough. It would serve you well. But if you have a need where you have to modify the content of messages, then you have to do some customization and enhancements that would do the job.

The purpose of this blog post is to introduce you to a method where you can not only route messages using the System.ServiceModel.Routing namespace but also modify its contents.


Detail


Let us start by taking a quick look at an implementation of System.ServiceModel.Routing,where the implementation is only routing the messages.

1. Create a WCF web service application.
2. Modify the. svc file to have following markup:
<%@ ServiceHost
Language="C#"
Debug="true"
Service="System.ServiceModel.Routing.RoutingService" %>


3. Remove any code behind file or interface files.
4. Make changes to web.config as following:


 version="1.0"?>
<configuration>
 <system.web>
  <compilation debug="true"
      targetFramework="4.0">
   <assemblies>
    <add assembly="System.ServiceModel.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
   </assemblies>
  </compilation>
 </system.web>
 <system.serviceModel>
  <behaviors>
   <serviceBehaviors>
    <behavior name="routingBehavior">
     <routing
      routeOnHeadersOnly="true"
      filterTableName="filters"/>

     <serviceDebug includeExceptionDetailInFaults="true"/>
     <serviceMetadata httpGetEnabled="true"/>
    </behavior>
   </serviceBehaviors>
  </behaviors>
  <bindings>;
   <basicHttpBinding>
    <binding
     name="basicHttp"
     maxReceivedMessageSize="2147483647"
     maxBufferPoolSize="2147483647"
     maxBufferSize="2147483647"
     openTimeout="00:02:10"
     sendTimeout="00:10:30"
     receiveTimeout="00:10:30">
     <readerQuotas maxStringContentLength="2147483647"
          maxArrayLength="67108664"/>
    </binding>
   </basicHttpBinding>
   <wsHttpBinding>
    <binding name="wsHttp"
       maxReceivedMessageSize="2147483647"
       openTimeout="00:02:10"
       sendTimeout="00:10:30"
       receiveTimeout="00:10:30">
     <readerQuotas maxStringContentLength="2147483647" />
    </binding?
   </wsHttpBinding>
  </bindings>
  <routing>
   <filters>
    
    <filter
     name="TargetServiceFilter"
     filterType="Action"
     filterData="http://tempuri.org/ITargetService/GetServiceData"/>
 
   </filters>
   <filterTables>
    
    <filterTable name="filters">
     <add filterName="TargetServiceFilter"
       endpointName="TargetService" />
    </filterTable>
   </filterTables>
  </routing>
  <services>
   
   <service name="System.ServiceModel.Routing.RoutingService"
      behaviorConfiguration="routingBehavior">
    <endpoint
     address="/identity"
     binding="wsHttpBinding"
     contract="System.ServiceModel.Routing.IRequestReplyRouter"
     name="TargetService"/>
    <host>
     <baseAddresses>
      <add baseAddress="http://localhost:44531/Router.svc"/>
     </baseAddresses>
    </host>
   </service>
  </services>
  
  <client>
   <endpoint
    address="http://localhost:2932/TargetService.svc/basic"
    binding="basicHttpBinding"
    bindingConfiguration="basicHttp"
    contract="*"
    name="TargetService"/>
  </client>
  <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
 </system.serviceModel>
 <system.webServer>
  <modules runAllManagedModulesForAllRequests="true"/>
 </system.webServer>
 
</configuration>



The above implementation is for simple routing where any messages that are pointing to the router would be routed to TargetService (definition details are mentioned above).

In the following section we would take the above implementation and change it to allow us have the ability to modify the message that is reaching the router before it is forwarded to the target service.

Steps to enable message modifications for router service


In order for us to accomplish that we would use custom filter. A custom filter would allow us to plug in our class. This class would be invoked when ever a message is received by the router. There few conditions that must be met for that class to work. The most important condition is that this class should inherit from MessageFilter  abstract class. This class is part of System.ServiceModel.Dispatcher
 namespace.
Step 1: Create a new class called RegularMessageFilter. This class would be our custom message filter.


 public class RegularMessageFilter : MessageFilter
 {
  #region Private member
 
  private RegularMessageFilterGroup group;
  private string groupName;
 
  #endregion Private member
 
  #region Constructor(s)
 
  public RegularMessageFilter()
  {
  }
 
  public RegularMessageFilter(string groupName)
  {
   if (string.IsNullOrEmpty(groupName)) { throw new ArgumentNullException("groupName"); }
 
   this.groupName = groupName;
  }
 
  #endregion Constructor(s)
 
  #region Private methods
 
  private void SetGroup(RegularMessageFilterGroup group)
  {
   if (group == null) { throw new ArgumentNullException("group"); }
 
   this.group = group;
  }
 
  #endregion Private methods
 
  #region Overrides
 
  public override bool Match(System.ServiceModel.Channels.Message message)
  {
   throw new NotSupportedException();
  }
 
  public override bool Match(System.ServiceModel.Channels.MessageBuffer buffer)
  {
   throw new NotSupportedException();
  }
 
  protected override IMessageFilterTable CreateFilterTable()
  {
   return new RegularMessageFilterTable();
  }
 
  #endregion Overrides
 
  #region Private helper classes
 
  private class RegularMessageFilterGroup
  {
   #region Private members
 
   private string name;
   private List<RegularMessageFilter> filters = new List<RegularMessageFilter>();
   private IEnumerator<RegularMessageFilter> currentPosition;
 
   #endregion Private members
 
   #region Constructor(s)
 
   public RegularMessageFilterGroup(string name)
   {
    this.name = name;
   }
 
   #endregion Constructor(s)
 
   #region Private methods
 
   private void EnsureEnumerator()
   {
    if (this.currentPosition == null)
    {
     this.currentPosition = filters.GetEnumerator();
     this.currentPosition.MoveNext();
    }
   }
 
   private void AdvanceEnumerator()
   {
    if (!this.currentPosition.MoveNext())
    {
     //Reached the end, clear the enumerator
     this.currentPosition.Dispose();
     this.currentPosition = null;
    }
   }
 
   #endregion Private methods
 
   #region Public methods
 
   public RegularMessageFilter GetNext()
   {
    this.EnsureEnumerator();
    RegularMessageFilter next = (RegularMessageFilter)this.currentPosition.Current;
    this.AdvanceEnumerator();
    return next;
   }
 
   public bool Match(RegularMessageFilter filter)
   {
    this.EnsureEnumerator();
    RegularMessageFilter currentFilter = (RegularMessageFilter)this.currentPosition.Current;
    bool matched = Object.ReferenceEquals(currentFilter, filter);
    if (matched)
    {
     this.AdvanceEnumerator();
    }
    return matched;
   }
 
   #endregion Public methods
 
   #region Internal methods
 
   internal void AddFilter(RegularMessageFilter filter)
   {
    if (this.currentPosition != null)
    {
     throw new InvalidOperationException("Cannot add while enumerating");
    }
    this.filters.Add(filter);
    filter.SetGroup(this);
   }
 
   #endregion Internal methods
  }
 
  private class RegularMessageFilterTable : IMessageFilterTable
  {
   #region Constants
 
   private const string YOUR_NAMESPACE = "http://yournamespace/";
   private const string ENDPOINT_MESSAGE_FILTER_KEY_NAME = "System.ServiceModel.Routing.EndpointNameMessageFilter.Name";
 
   #endregion Constants
 
   #region Private members
 
   private Dictionary<MessageFilter, TFilterData> filters = new Dictionary<MessageFilter, TFilterData>();
   private Dictionary<stringRegularMessageFilterGroup> groups = new Dictionary<stringRegularMessageFilterGroup>();
 
   #endregion Private members
 
   #region Contructor(s)
 
   public RegularMessageFilterTable()
   {
   }
 
   #endregion Contructor(s)
 
   #region Public methods
 
   public bool GetMatchingFilter(MessageBuffer messageBuffer, out MessageFilter filter)
   {
    throw new NotImplementedException();
   }
 
   public bool GetMatchingFilter(Message message, out MessageFilter filter)
   {
    throw new NotImplementedException();
   }
 
   public bool GetMatchingFilters(MessageBuffer messageBuffer, ICollection<MessageFilter> results)
   {
    bool foundSome = false;
    foreach (RegularMessageFilterGroup group in this.groups.Values)
    {
     RegularMessageFilter matchingFilter = group.GetNext();
     results.Add(matchingFilter);
     foundSome = true;
    }
 
    return foundSome;
   }
 
   public bool GetMatchingFilters(Message message, ICollection<MessageFilter> results)
   {
    bool foundSome = false;
    foreach (RegularMessageFilterGroup group in this.groups.Values)
    {
     RegularMessageFilter matchingFilter = group.GetNext();
     results.Add(matchingFilter);
     foundSome = true;
    }
 
    return foundSome;
   }
 
   public bool GetMatchingValue(MessageBuffer messageBuffer, out TFilterData value)
   {
    value = default(TFilterData);
    List results = new List();
    bool outcome = this.GetMatchingValues(messageBuffer, results);
    if (results.Count > 1)
    {
     throw new MultipleFilterMatchesException();
    }
    else if (results.Count == 1)
    {
     value = results[0];
    }
    return outcome;
   }
 
   public bool GetMatchingValue(Message message, out TFilterData value)
   {
    SetupMessage(message, "TestValue");
    value = default(TFilterData);
    List results = new List();
    bool outcome = this.GetMatchingValues(message, results);
    if (results.Count > 1)
    {
     throw new MultipleFilterMatchesException();
    }
    else if (results.Count == 1)
    {
     value = results[0];
    }
    return outcome;
   }
 
   public bool GetMatchingValues(MessageBuffer messageBuffer, ICollection results)
   {
    bool foundSome = false;
    foreach (RegularMessageFilterGroup group in this.groups.Values)
    {
     RegularMessageFilter matchingFilter = group.GetNext();
     results.Add(this.filters[matchingFilter]);
     foundSome = true;
    }
 
    return foundSome;
   }
 
   public bool GetMatchingValues(Message message, ICollection results)
   {
    bool foundSome = false;
    object httpRequestMessageObject;
    if (message.Properties.TryGetValue(ENDPOINT_MESSAGE_FILTER_KEY_NAME, out httpRequestMessageObject))
    {
     foreach (RegularMessageFilterGroup group in this.groups.Values)
     {
      RegularMessageFilter matchingFilter = group.GetNext();
      if (matchingFilter.groupName == httpRequestMessageObject.ToString())
      {
       results.Add(this.filters[matchingFilter]);
       foundSome = true;
      }
     }
    }
    return foundSome;
   }
 
   public void SetupMessage(Message requestMessage, string customMessageHeaderValue)
   {
    if (!string.IsNullOrEmpty(customMessageHeaderValue))
    {
     MessageHeader messageHeaderForCookie = MessageHeader.CreateHeader("CustomHeader", YOUR_NAMESPACE, customMessageHeaderValue);
     requestMessage.Headers.Add(messageHeaderForCookie);
    }
   }
 
   public void Add(MessageFilter key, TFilterData value)
   {
    RegularMessageFilter filter = (RegularMessageFilter)key;
    RegularMessageFilterGroup group;
    if (!this.groups.TryGetValue(filter.groupName, out group))
    {
     group = new RegularMessageFilterGroup(filter.groupName);
     this.groups.Add(filter.groupName, group);
    }
    group.AddFilter(filter);
    this.filters.Add(key, value);
   }
 
   public bool ContainsKey(MessageFilter key)
   {
    throw new NotImplementedException();
   }
 
   public bool Remove(MessageFilter key)
   {
    throw new NotImplementedException();
   }
 
   #endregion Public methods
 
   #region Public members
 
   public ICollection<MessageFilter> Keys
   {
    get { throw new NotImplementedException(); }
   }
 
   public bool TryGetValue(MessageFilter key, out TFilterData value)
   {
    throw new NotImplementedException();
   }
 
   public ICollection Values
   {
    get { throw new NotImplementedException(); }
   }
 
   public TFilterData this[MessageFilter key]
   {
    get
    {
     throw new NotImplementedException();
    }
    set
    {
     throw new NotImplementedException();
    }
   }
 
   public void Add(KeyValuePair<MessageFilter, TFilterData> item)
   {
    throw new NotImplementedException();
   }
 
   public void Clear()
   {
    throw new NotImplementedException();
   }
 
   public bool Contains(KeyValuePair<MessageFilter, TFilterData> item)
   {
    throw new NotImplementedException();
   }
 
   public void CopyTo(KeyValuePair<MessageFilter, TFilterData>[] array, int arrayIndex)
   {
    throw new NotImplementedException();
   }
 
   public int Count
   {
    get { throw new NotImplementedException(); }
   }
 
   public bool IsReadOnly
   {
    get { throw new NotImplementedException(); }
   }
 
   public bool Remove(KeyValuePair<MessageFilter, TFilterData> item)
   {
    throw new NotImplementedException();
   }
 
   public IEnumerator<KeyValuePair<MessageFilter, TFilterData>> GetEnumerator()
   {
    throw new NotImplementedException();
   }
 
   IEnumerator IEnumerable.GetEnumerator()
   {
    throw new NotImplementedException();
   }
 
   #endregion Public members
  }
 
  #endregion Private helper classes
 }


If you notice the above code snippet, there is a function called 'SetupMessage'. This function is at the heart of this blog. In this function we have modified the incoming message before it is being forwarded to the target service.

Step 2: Modify the web.config file to incorporate the custom message filter that we created in the previous step. This will be done simply by commenting out the already created filter and adding the custom filter. Here is how it would be implemented.

    
 
    <filter
     name="TargetServiceFilter"
     filterType="Custom"
     customType="RoutingWithMessageModification.Service.RegularMessageFilter, RoutingWithMessageModification.Service"
     filterData="TargetService"/>


Conclusion

We have seen that using the out of the box router service, we can add our custom filter that can be used to modify message contents. The above example only adds a message header to the out going messages. But using the custom filter we can add any logic to manipulate messages.