Windows Identity Foundation : A SignInResponse message may only redirect within the current web application

We have run into an issue in the WSFederationAuthenticationModule class within WIF.

The bug has been posted here on Microsoft connect.
http://connect.microsoft.com/site642/feedback/details/573589/wsfederationauthenticationelement-web-config-requires-trailing-slash-after-home-realm-otherwise-an-error-occurs

Basically the issue comes when the application requesting authentication from your STS sends a redirection url without a trailing slash. The slash cannot always be guaranteed as the return URI is created from the accessed application URI. Therefore if a user bookmarks the wrong URI or a link doesn’t have the trailing slash you will get the above exception message.

In trying to fix this problem I had a look through the WSFederationAuthenticationModule’s public event listings. None of the events that we could see occurred before the offending code in OnAuthenticateRequest().

The workaround listed on Microsoft Connect was quite bad as it forced us to check every single request in each RP to ensure that the trailing slash was in the URI, and if not redirect back to itself with the trailing slash.

I came up with a simpler solution to the problem which only needs a change to the STS itself. Since we couldn’t get into a public event before the offending code we added a HttpModule to the pipeline and ensured it ran before the WS modules.

This custom http module simply checked the ‘ru’ return URI field (within the wctx entry in the query string) for a trailing slash and if none was provided redirected back to itself with the trailing slash in the ‘ru’ field.

I’ve updated the Microsoft Connect website for the new work around.

Advertisements

Getting back into it.

Well I’ve been back from the holiday for a month or so. Been staying away from the blog for a while as I’ve had so much work to do since I got back that I need to prioritise.

I’m currently working on starting a new project in ASP.NET MVC 3 so you might see a few posts pop up about that. At the moment we are just going through the early stages of release planning and story estimation.

Stay tuned.

Multi Tenant update

Hi,
I’ve received messages and I know a few of you are waiting for a good tutorial on multi tenancy.

I’ve been busy working as I’m going on a trip and will be away for the next 6 weeks. So it’s going to have to wait, we haven’t gone live with my changes I’ve made at work yet as they are not complete however in development it is working very nicely.

I’ll write up some posts when I get back. Basically my solution for the back-end involved:

  • MEF for drop-in client overrides of business logic in a services layer
  • EF 4.1 for POCO classes implementing an interface which allows for a hash set of key,value pair custom fields

This gives us a flexible back-end. As for the UI we have PHP, Webforms and MVC so that’s taking quite a bit of work to change. There are already great tutorials on multi tenancy MVC so I’d refer to those.

Looking forward to getting into it when I’m back.

IIS 6 Session timeout issue (Web.Config cannot solve all timeout problems)

We were receiving calls from a client saying that they kept being kicked out of one of our systems quite regularly usually after 20-30 mins of inactivity.

We got to work and firstly checked the usual suspects, the web.config file sessionState timeout and the forms timeout for forms authentication. Both of those were set to > 2 hours so it couldn’t have been those.

I debugged on my local machine and found that everything was working fine and the session was being killed after the correct timeout stated in the web.config file. It seemed it was a server configuration issue. Now our situation is complex as we share authentication across multiple systems including legacy PHP code, So i tried all of those configs, to no avail.

At last eureka! It seems the actual application pool was being recycled after 20 mins of inactivity. This was an application pool being used by only 1 client so was not being hit as often as most. If your having similar problems check your application pool’s session time out values and application recycle values.. Ours was set to 20 mins of inactivity which I believe is the default.

SaaS Multitenant ASP.NET 4.0 – Step 1 Introduction

Introduction

This is the first in what I have planned to be a series of posts all about moving your application(s) to a multi-tenant architecture.

I have noticed that there really isn’t enough being done in the way of frameworks and tutorials in the area of multitenancy, especially using .NET and the Entity Framework. Please learn with me as I tackle the many problems I am facing right now moving our suite of products to a more Saas friendly environment.

Software as a service

I’m sure most have heard the buzz phrase “Software as a service (SaaS)”, I won’t go into too many details here about the model itself, a quick google search will find many articles that cover the concept much better than I could here. Basically it can be very cost effective for ISV’s as it pushes configuration over customisation, low running costs, subscription paid services and it fits perfectly in the cloud. I really like the concept as a developer because it means less custom coding for client specific functionality, makes it much easier to manage versions of code (when clients are on the same branch) and it is extendable by its nature so gives room for evolutions of the software’s purpose.

This series is aimed at the actual implementation of a multi-tenant architecture using .NET 4.0 technologies. This essentially means allowing multiple clients (or tenants) to run on the same codebase with their own custom fields, themes, workflows and other features.

When implementing this architecure some problems will be faced such as:

  • How many databases will we need? 1 per client, 1 database for all clients?, etc.
  • How will we manage custom client fields that need to persisted to that database?
  • How will the UI change to reflect those extra fields?
  • How do we manage custom reporting?
  • Where will we place business logic that will change per client?
  • How do we inject extra business logic and validation for client specific decisions?
  • How will we manage custom client workflows?
  • How do offer particular features to only those clients who have paid for them?
  • If a client wants to change a theme to suit their intranet’s theme can we allow for this?
  • How will we handle users, login/logout methods, roles and permissions so that the security aspect of the system is abstracted well enough to be easily defined per client? How will the our user’s manage their security roles and users?
  • Is it worth doing all this work, or should we just make client changes on their own versions of code? (Works for a certain threshold of clients to resources and for systems that don’t need much in the way of customisation)
  • How do we build this architecture in the most elegant way. And when I say elegant I mean without needing 20 layers of abstraction

If your still with me you’ll see that multi-tenancy poses quite a few questions and is not something that can be done overnight. The benefits are that you get to manage only one branch of code and can have quite a few clients on there happy without needing to do some serious customisation of the product and without needing to manage a seperate version of code for each client (headache!).

The cons are obviously the upfront cost in time and effort. I’m am facing this problem now and hopefully this guide and the relevant source will help those looking to solve this problem using .NET technolgies.

So stay with me and lets work through this headache together. Up next will be our data access layer and database design.

Cheers

EF 4.1 DbContext Issue : Manually opening and closing the database connection

As I’m sure many of you are aware the Entity Framework will create and close database connections automatically when needed. This is great most of the time, however when we want to manually configure the connection for performance or to perform a list of actions within a transaction we don’t want the entity framework to automatically close our connection.

I’ve found an issue where I’m trying to manually manage my DbContext connection and the DbContext API does not want to let me.
(I’m using Sql Server 2005 and am trying to avoid transaction promotion to the DLC which means I want to do all of my queries on the same connection).

In ObjectContext land, when I call ObjectContext.Connection.Open() I am manually opening the connection and the documentation states on MSDN that this connection will NOT be closed until I call the Close() method or dispose of the context.

It seems calling DbContext.Database.Connection.Open() does not give the same results. When called I watch the context close and reopen for each query. Below is the code that I am trying to write that presents the problem.

DbContext version:


            dbContext.Database.Connection.Open();
            using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
            {
                  // perform a list of queries
                 // the connection will close
                 scope.Complete();
                 dbContext.Database.Connection.Close();
            }

ObjectContext version:


            (dbContext as IObjectContextAdapter).ObjectContext.Connection.Open();
            using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
            {
                  // perform a list of queries
                 // The connection will not close!
                 scope.Complete();
                 (dbContext as IObjectContextAdapter).ObjectContext.Connection.Close();
            }

So the fix for now is to get the ObjectContext from your DbContext. But can someone explain what the difference is and is this by design?

Faking DbContext in Entity Framework 4.1 with a generic repository

Update 30/11/2011: FakeDbSet implementation update Please see the new and improved FakeDbSet Here

Update 16/06/2011:  Added step (2) description of how to implement Set<>() method in your original DbContext so that it returns IDbSet<>. Also added SaveChanges() to expose the context as a unit of work. + A little reorganisation.

Faking of the new Entity Framework 4.1 DbContext can be done quite simply by following these steps:

1. Create a common interface for your particular DbContext type.

I’m using a generic repository so my interface only needs to implement the Set method. But you could of course expose all your collections through this interface.

    public interface IMainModuleContext
    {
        IDbSet<Person> People { get; set; } // My collections...
        IDbSet<TEntity> Set<TEntity>() where TEntity : class;
        void SaveChanges();
    }

Notice how our DbSet collections IDbSet instead of DbSet. This is because we will use an in-memory representation of the DbSet collection called FakeDbSet which implements IDbSet.

If you are exposing all of your collections and using model-first this could be generated with a T4 Template to save development time. Ensure your real DbContext implements this interface, and that your repository will take a IMainModuleContext instead of the concrete type.

2. Now lets make sure our original context (mine is called MainModuleContext) is implementing this interface. Example of the code to do this is below:

public partial class MainModuleContext : DbContext, IMainModuleContext
{
    public IDbSet<Person> People { get; set; }
    public MainModuleContext() : base() {}
    public IDbSet<TEntity> Set<TEntity>() where T : class
    {
        return base.Set<TEntity>();
    }

    public void SaveChanges()
    {
        base.SaveChanges();
    }
    // Other methods
}

Notice our properties must return IDbSet instead of DbSet. This is easy since the EF team have included the IDbSet interface for us.

3. Now we will create a fake dbset (an in-memory representation of a dbset)

    public class FakeDbSet<T> : IDbSet<T> where T : class
    {
        private HashSet<T> _data;

        public FakeDbSet()
        {
            _data = new HashSet<T>();
        }

        public virtual T Find(params object[] keyValues)
        {
            throw new NotImplementedException();
        }

        public T Add(T item)
        {
            _data.Add(item);
            return item;
        }

        public T Remove(T item)
        {
            _data.Remove(item);
            return item;
        }

        public T Attach(T item)
        {
            _data.Add(item);
            return item;
        }

        public void Detach(T item)
        {
             _data.Remove(item);
        }

        Type IQueryable.ElementType
        {
            get { return _data.AsQueryable().ElementType; }
        }

        Expression IQueryable.Expression
        {
            get { return _data.AsQueryable().Expression; }
        }

        IQueryProvider IQueryable.Provider
        {
            get { return _data.AsQueryable().Provider; }
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return _data.GetEnumerator();
        }

        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
            return _data.GetEnumerator();
        }

        public T Create()
        {
            return Activator.CreateInstance<T>();
        }

        public ObservableCollection<T> Local
        {
            get
            {
            return new ObservableCollection<T>(_data);
            }
        }

        public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : class, T
        {
            return Activator.CreateInstance<TDerivedEntity >();
        }
    }

4. Now implement your fake context. The only tricky thing here is the Set method needs to use reflection to find the property we are after.


    public partial class FakeMainModuleContext : IMainModuleContext
    {
        public IDbSet<Person> People { get; set; }
        public IDbSet<T> Set<T>() where T : class
        {
            foreach (PropertyInfo property in typeof(FakeMainModuleContext).GetProperties())
            {
                if (property.PropertyType == typeof(IDbSet<T>))
                    return property.GetValue(this, null) as IDbSet<T>;
            }
            throw new Exception("Type collection not found");
        }

        public void SaveChanges()
        {
             // do nothing (probably set a variable as saved for testing)
        }

        public FakeMainModuleContext()
        {
            // Set up your collections
            People = new FakeDbSet
            {
                new Person() { FirstName = "Brent" }
            };
        }

You can now swap out your DbContext with a FakeDbContext for unit testing.

Javascript parseInt gotcha (All browsers)

I wanted to keep this blog to put up interesting gotchas that I’ve found whilst programming. This is definitely one of the craziest I’ve seen.

I had a problem with my jquery calendar where I was parsing a string as an int. I was calling this:

parseInt("08");

So you would assume an int of 8 yeah?
The actual returned value is ZERO, which was a bit of a shock to me. Apparently the javascript parseInt function will take a string leading with a zero as an octal number. To force it to read a base 10 number you will have to call

parseInt("08", 10);

See this post for a great explanation http://www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256C85006A6604. Its amazing how long I have been programming in javascript and have never picked up this one..

Jquery AJAX call to WCF Service returning custom objects

As the web gets faster and ajax becomes more and more used you will find clients are expecting a web experience close to that of a desktop application. JQuery together with Ajax make this task a whole lot easier. I’m currently writing a control to make room bookings via calender (you can see alot of these if you search for jquery plugins) our needs are a little different so I’m rolling my own and I thought I’d show just how easy it is to add ajax functionality to your page.

We all know the update panel is a horrible control. Sure it makes life easy but it is slow, has massive viewstate issues and not very developer friendly since it doesn’t allow for much customisation.

If you haven’t had a look at JQuery yet I suggest you should head over to jquery.com and have a look. This library makes our lives as developers a whole lot easier, and is great for AJAX calls which is what I’ll be talking about today.

I’m assuming you have basic experience with WCF and JQuery, and of course you know what ajax is (if not have a look a gmail. Notice how the page doesn’t refresh when you change folders, and mail is added to your html inbox automatically.. great user experience.)

Lets set up a simple web service. Add a new item to your web project and choose WCF Service. Create a contract as shown below:


    [Serializable]
    public class BookingViewModel
    {
        public int bookingID;
        public string description;
    }

    [ServiceContract(Name = "TestBookings", Namespace = "MyNamespace")]
    public interface ITestBookings
    {
        [OperationContract]
        [WebInvoke(Method="POST",
            BodyStyle=WebMessageBodyStyle.Wrapped,
            ResponseFormat=WebMessageFormat.Json)]
        List<BookingViewModel> SearchBookings();
    }

Now above I’ve created an interface which will be my WCF contract. I’ve declared my method as Web Invokable (can be called from javascript) and will be returning values encoded in Json.

At this point we have our contract, you should create a simple class to test that we have wcf set up correctly.

    [ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
    public class TestBookings: ITestBookings
    {
          public List<BookingViewModel> SearchBookings()
         {
               return new List<BookingViewModel>
               {
                     new BookingViewModel
                     {
                            bookingID = 100,
                            description = "bob booked hotel"
                     },
                     new BookingViewModel
                     {
                            bookingID = 101,
                            description = "tim booked hotel"
                     }
               };
         }
    }

You’ll need to set up your serviceModel and endpoints in your web.config file. Heres a sample one:


    <system.serviceModel>
        <services>
            <clear />
            <service name="Namespace.TestBookings">
                <endpoint address="" binding="webHttpBinding" behaviorConfiguration="TestBehaviour"  contract="Namepsace.ITestBookings"/>
            </service>
        </services>

        <behaviors>
            <endpointBehaviors>
                <behavior name="TestBehaviour">
                    <webHttp/>
                </behavior>
            </endpointBehaviors>
            <serviceBehaviors>
                <behavior>
                    <serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
                    <serviceDebug includeExceptionDetailInFaults="true" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
    </system.serviceModel>

Basically the important parts are the binding=”webHttpBinding” and the behaviour config for .

Now right click on your svc file, choose set as start page and then run your app. You should see the default svc page generated by .NET. If not you will have to troubleshoot I won’t go into debugging the service here as its out of scope but a quick google of the error should find what you need. Otherwise comment and I’ll see if I can help.

At this point we can use JQuery to call the WCF service


<script>
    $(document).ready(function () {
            $.ajax({
                type: "POST",
                url: "YOUR-URL/TestBookings.svc/SearchBookings",
                data: "{}",
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (data) {
                    var bookings = data.SearchBookingsResult;
                    alert(bookings[0].description);
                },
                error: function (xhr) {
                    alert(xhr.responseText);
                    return;
                }
            });
});

</script>

If everything worked correctly you should get an alert stating the description of booking number 1. This is so easy, however there is so much going on in the backend for your c# objects to be projected onto javascript. The .NET team have done amazing work here. And JQuery is the icing on the cake.

Jquery Visual Studio 2010 Intellisense in Javascript (JS) file

Hey guys,
Just a little trick I came along today, If you’re after Jquery Intellisense in your js file your going to need the jquery-x.x.x-vsdoc.js file which comes with the jquery package.

Simply add this to the top of your JS file

/// <reference path="jquery-x.x.x-vsdoc.js" />

Then Ctrl+Shift+J will reset Intellisense for javascript. Now ctrl+space and you should get the usual intellisense.

You should automatically get the intellisense in your aspx file (for script tags) if referencing your normal jquery file (and the vsdoc file is in the same directory as that reference) as automatic support for that is inbuilt.

Cheers!