Category Archives: Guides

Protect Glimpse.axd with your custom runtime policy

Let’s first start with a quick recap on how Glimpse decides whether or not to aggregate and store diagnostic data for a specific request and how it protects its own resources for unauthorized access. (Glimpse resources are, for instance, the Glimpse client JavaScript file, the metadata that makes up the Glimpse panel, but most importantly the aggregated diagnostic data of the last and previous requests.)

To make sure Glimpse doesn’t show possibly sensitive diagnostic data, it allows you to create a custom runtime policy. This, based on your rules, authorizes or prevents the Glimpse Runtime from returning the aggregated data or even from running in the first place – all of this is determined per request. The Glimpse cookie for instance, which is what drives the “Turn Glimpse On” button, is checked by the ControlCookiePolicy, and is not used to prevent access to aggregated data but rather to inform the Glimpse Runtime whether or not it should collect information during the execution of a request.

All is not lost however. Glimpse is secure by default because it registers, out of the box, the LocalPolicy. The LocalPolicy is a runtime policy that checks whether or not a request has been made from the local machine and if this is not the case, then Glimpse will not aggregate data and certainly not return (previously) aggregated data. This is also the policy that must be ignored in the web.config if you would like to get Glimpse diagnostics from a remote server.

Now if you remove the LocalPolicy, then basically everything is out in the open. There is nothing protecting you from having Glimpse gathering diagnostics and returning this to the person making the request. You could disable Glimpse completely in the web.config by setting the defaultRuntimePolicy=”Off” in the glimpse config section, but then there is not much for you to personally get either.

So you need to replace the LocalPolicy with your own custom security policy. Which sounds harder than it is – usually only a few lines of code are involved. There might already be an example of such a policy in your project (albeit commented out) if you installed the Glimpse.AspNet NuGet package, just look for a file named GlimpseSecurityPolicy.cs

GlimpseSecurityPolicyExample

What does this example policy do? Well if you compile this as is, then Glimpse will discover this policy and will ask the policy, by calling Execute at then end of a request (ExecuteOn has a value of RuntimeEvent.EndRequest), whether the client is allowed to see the aggregated data or not. This example will only allow this if the current authenticated user is a member of the Administrator role, but you can put any kind of logic in there if you want, just keep in mind that this will be called for every request that is being monitored by Glimpse.

In case you’re wondering why the check is done at the end of the request instead of the beginning (as Glimpse might already have monitored the request then), it’s because some things like the current User might not yet be set in the beginning, hence disabling Glimpse for every request. But depending on your logic (IP check for instance) you can change this value to RuntimeEvent.BeginRequest

Securing Glimpse.axd

Now all of this was already possible with previous versions of Glimpse. But there was one thing that was not protected by such a custom security policy and that was the Glimpse.axd. This was due to the fact that if the same runtime policies would have been applied, then the Glimpse.axd might not be accessible in the first place because the ControlCookiePolicy could not find the Glimpse cookie and you need (at least to begin with) the Glimpse.axd to set the cookie (and maybe add the bookmarklets to your favorites bar for later use). This is why the runtime policies were explicitly being ignored by Glimpse for the default resource aka Glimpse.axd

You might wonder why you would secure the Glimpse.axd in the first place? Although it doesn’t give you access to the aggregated data, there is still quite some information being shown that might be useful to persons with bad ideas. Today the Glimpse.axd shows you how Glimpse is configured, maybe tomorrow we would like to provide you with the possibility to make changes to the configuration at runtime, who knows.

Securing Glimpse.axd as we used to do
There were several ways to lock the Glimpse.axd down because Glimpse wouldn’t. I’ll only show two of them, because some others are a little bit hacky and those two mentioned below can still be used today if you want to:

  1. Leverage the ASP.NET Security Model : By adding a location element to your web.config you can restrict access to the Glimpse.axd to Administrators only. Of course this is only possible if your authorization checks can be satisfied with a role checkglimpseaspnetlocation
  2. Security by obscurity : We’ve been talking about Glimpse.axd but there is no compelling reason to keep it named like that, you can name it whatever you like as long as you adapt your web.config accordingly you are good to go. But again, it’s not bullet proof if somebody can guess really wellSecurityByObscurity

Securing Glimpse.axd the way forward
As of release 1.7.0 of Glimpse, you can now secure the Glimpse.axd by using the same custom security policy as shown above. This has the benefit that your authorization rules with regards to Glimpse are stored in one place being your custom security policy and you no longer need to rely on security by obscurity or role checks (if that was even possible). And there is only one thing that you need to do for that which is modifying the ExecuteOn property of your custom security policy, so that it will not only be called at BeginRequest or EndRequest but also when a resource is being executed (our default resource aka Glimpse.axd) by updating ExecuteOn to:

public RuntimeEvent ExecuteOn
{
    // The bit flag that signals to Glimpse that it should run on either event
    get { return RuntimeEvent.Endrequest | RuntimeEvent.ExecuteResource; }
}

GlimpseSecurityPolicyExampleWithExecuteResource

Voila, that’s all there is to it

Now there are no more reasons why your Glimpse.axd can’t be secured. If there is something not clear or working, don’t hesitate to contact us on our issues list

Extending your Tab – Your code, your plugins, part 3

So far we have covered a couple of different cases around how you could introduce custom Tabs into your system to gain a better understanding of how your system is operating (Creating a simple Tab – Your code, your plugins, part 1 and Creating a typical Tab – Your code, your plugins, part 2).

These tabs have been great to get up and running, but there is a chance that after a while, you may want to get more from your tab. Specifically, to extend its look and feel, and even to enhance the data that you are seeing inside the plugin.

New Concepts

  • Controlling the layout of your tab
  • Render compound/nested objects
  • Pivoting the root table layout

Use Case 3: Show the content of a shopping cart style component you might have written, using a custom layout

This time around, it’s the same use case that we saw in part 2 but we are adding on the fact that we would like to control the layout. We want to augment what we see so the layout is clear and the data representation matches our mental model, not just the object structure we happen to be dealing with. We want to control the headers/titles, order of the columns, prefixes/postfixes, styling, etc.

Existing code
I’m going to assume that you have seen how we got the base plugin up and running (if you haven’t, checkout part 2). The code in question is that of a typical Tab that returns an object collection.

public class TabCart : AspNetTab
{
    public override string Name
    {
        get { return "Cart"; }
    }

    public override object GetData(ITabContext context)
    {
        var cart = ShoppingCart.GetCart(context.GetHttpContext());
        var items = cart.GetCartDetials();

        return items;
    }

    public override RuntimeEvent ExecuteOn
    {
        get { return RuntimeEvent.EndSessionAccess; }
    }
}

Controlling the layout of your tab
Problem
By default when we return data from our ITab.GetData() method, the object contains no styling information. The rendering engine gets us pretty close to what we want to see but still doesn’t get us all the way there.

Solution
As it turns out Glimpse supports an extension model which favours Interface Segregation. This is just a fancy way of saying that extra functionality can be added to a Tab by making a Tab implement a given interface. This interface will augment the Tab and allow it to perform functions that a base Tab would would otherwise not be able to.

This is what we would like to see:
LayoutTab
You will note that it looks similar to the previous version of the tab we had, but its layout is different.

Sample Code
In this case we are going to add on the ITabLayout interface which requires that we add on a GetLayout() method. This method should return an object which describes how the data is to be structured or laid out. To help controlling these layouts we have a fluent API (which was created by Kristoffer Ahl of Fluent Security fame). The following gives you a basic taste of what you could do to achieve the above:

using Glimpse.AspNet.Extensibility; 
using Glimpse.AspNet.Extensions;
using Glimpse.Core.Extensibility;
using Glimpse.Core.Tab.Assist;
using MvcMusicStore.Models;

namespace MvcMusicStore.Framework
{
    public class TabCart : AspNetTab, ITabLayout
    {
        //NEW CODE
        private static readonly object Layout = TabLayout.Create()
                .Row(r =>
                {
                    r.Cell("{{albumTitle}} ({{albumId}})").AsKey().WithTitle("Album (Id)");
                    r.Cell("albumPrice").AlignRight().Prefix("$").WidthInPixels(100).WithTitle("Price");
                    r.Cell("genreName").WithTitle("Genre");
                    r.Cell("artistName").WithTitle("Artist");
                    r.Cell("count").Class("mono").WidthInPixels(70).WithTitle("Count");
                    r.Cell("dateCreated").WithTitle("Added");
                    r.Cell("recordId").WithTitle("Record Id");
                    r.Cell("cartId").WithTitle("Cart Id"); 
                }).Build();
        //NEW CODE
         
        public override string Name
        {
            get { return "Cart"; }
        }

        public override object GetData(ITabContext context)
        {
            var cart = ShoppingCart.GetCart(context.GetHttpContext());
            var items = cart.GetCartDetials();

            return items;
        }

        public override RuntimeEvent ExecuteOn
        {
            get { return RuntimeEvent.EndSessionAccess; }
        }

        //NEW CODE
        public object GetLayout()
        {
            return Layout;
        }
        //NEW CODE
    }
}

Render compound/nested objects
Problem
Having seen what the above has produced and the fact that we are starting to gain a real insight into how our shopping cart is operating, we have decided that we want to take things to a whole new level. We don’t want to repeat the shopping cart ID for every row (as we only want to see it once) and we want to see other aggregated information about out cart inside the tab (i.e. total value, etc).

Solution
As it turns out, Glimpse is capable of being able to render nested objects. When it detects a property which is a complex vs. primitive type, it recursively rips through that object and starts the rendering process again. For us, this means that we could construct an object that has the data we want listed above the table of cart entries.

Here is the next iteration of what we would like to see:
SummaryCartTab

Sample Code
Knowing that we want to show some more data, we can go back to the Tab and make some tweaks. Looking at the below, we can see that we have extended the model that we are returning and have added some more details to the meta data that’s returned.

public class TabCart : AspNetTab, ITabLayout
{
    //UPDATED CODE
    private static readonly object Layout = TabLayout.Create()
            .Cell("items", TabLayout.Create().Row(r =>
                {
                    r.Cell("{{albumTitle}} ({{albumId}})").AsKey().WithTitle("Album (Id)");
                    r.Cell("albumPrice").AlignRight().Prefix("$").WidthInPixels(100).WithTitle("Price");
                    r.Cell("genreName").WithTitle("Genre");
                    r.Cell("artistName").WithTitle("Artist");
                    r.Cell("count").Class("mono").WidthInPixels(70).WithTitle("Count");
                    r.Cell("dateCreated").WithTitle("Added");
                    r.Cell("recordId").WithTitle("Record Id");
                })).Build();
    //UPDATED CODE
     
    public override string Name
    {
        get { return "Cart"; }
    }

    public override object GetData(ITabContext context)
    {
        var httpContext = context.GetHttpContext();

        var cart = ShoppingCart.GetCart(httpContext);
        var items = cart.GetCartDetials();

        //UPDATED CODE
        var root = new
        {
            CartId = ShoppingCart.GetCartId(httpContext), 
            Total = items.Any() ? items.Sum(x => x.AlbumPrice).ToString() : "--", 
            Items = items
        };
        //UPDATED CODE

        return root;
    }

    public override RuntimeEvent ExecuteOn
    {
        get { return RuntimeEvent.EndSessionAccess; }
    }

    public object GetLayout()
    {
        return Layout;
    }
}

Pivoting the root table layout
Problem
As fate would have it, the above still isn’t good enough. We like the fact that the layout has progressed forward but, having seen other Tabs within Glimpse that are displayed more succinctly, we want to do more. In addition, the above rendering kinda squashes the Items table.

Solution
Another nice feature that the Glimpse rendering engine supports is the ability to pivot the way in which key/value Objects are displayed. When you do this, instead of seeing a key and value column, headings are rendered for the keys and the values are rendered in block under the corresponding header.

This time around, the below is what we would like to see:
PivotLayoutTab

Sample Code
Knowing that Glimpse can deal with nested objects and that we have the ability to pivot, we are going to group together the summary details. You will note that the pivot functionality is added by having our Tab implement the ILayoutControl interface. This is another example where we are using Interface Segregation to add functionality.

using System.Linq;
using Glimpse.AspNet.Extensibility; 
using Glimpse.AspNet.Extensions;
using Glimpse.Core.Extensibility;
using Glimpse.Core.Tab.Assist;
using MvcMusicStore.Models;

namespace MvcMusicStore.Framework
{
    public class TabCart : AspNetTab, ITabLayout, ILayoutControl
    {
        private static readonly object Layout = TabLayout.Create()
                .Cell("items", TabLayout.Create().Row(r =>
                    {
                        r.Cell("{{albumTitle}} ({{albumId}})").AsKey().WithTitle("Album (Id)");
                        r.Cell("albumPrice").AlignRight().Prefix("$").WidthInPixels(100).WithTitle("Price");
                        r.Cell("genreName").WithTitle("Genre");
                        r.Cell("artistName").WithTitle("Artist");
                        r.Cell("count").Class("mono").WidthInPixels(70).WithTitle("Count");
                        r.Cell("dateCreated").WithTitle("Added");
                        r.Cell("recordId").WithTitle("Record Id");
                    })).Build();
         
        public override string Name
        {
            get { return "Cart"; }
        }

        //NEW CODE
        public bool KeysHeadings
        {
            get { return true; }
        }
        //NEW CODE

        public override object GetData(ITabContext context)
        {
            var httpContext = context.GetHttpContext();

            var cart = ShoppingCart.GetCart(httpContext);
            var items = cart.GetCartDetials();

            var root = new
            {
                //UPDATED CODE
                Details = new {
                        CartId = ShoppingCart.GetCartId(httpContext), 
                        Total = items.Any() ? items.Sum(x => x.AlbumPrice).ToString() : "--"
                    },
                //UPDATED CODE
                Items = items
            };

            return root;
        }

        public override RuntimeEvent ExecuteOn
        {
            get { return RuntimeEvent.EndSessionAccess; }
        }

        public object GetLayout()
        {
            return Layout;
        }
    }
}

Working Sample
If you want to run what we have in the first sample, here is the link (94e9f99eda), or for the modified Tab, here is the link (e1fb2ca944), or for the finial pivoted Tab (e6d5eb04b2). As usual feel free to play around with it and modify.

Creating a typical Tab – Your code, your plugins, part 2

In the previous post – Creating a simple Tab – Your code, your plugins, part 1 – we looked at how we could take the data you store inside of a configuration object in your system, and create a tab which shows that data.

This time around we are going to be taking that a step further and looking at how we can customize how your Tab looks and how the data is displayed.

New Concepts

  • Creating a tab which renders a list of objects
  • Render data which is continuously changing
  • Controlling when a tab is executed

Use Case 2: Show the content of a shopping cart style of component you might have written

In this example, we have a shopping cart that our site uses to track items that a user is purchasing. When applying this to your own situation, think of the shopping cart as a generic representation of any component in your site that has transient state, based on the actions that the user performs.

For this case, our shopping cart is fairly simple and we wont be aiming to show more than the content of the shopping cart. In your own scenarios, you will likely be able to draw even more value than what we are showing here and start to apply some of the details/factors that exist in most real e-commerce solution (i.e. applied promotions, culture, discounts, markups, etc).

Existing code
Here is the general interface of the API that we are interacting with which manages the state of the cart:

public class ShoppingCart
{
    //...
    public static ShoppingCart GetCart(HttpContextBase context)
    {
        var cart = new ShoppingCart();
        cart.ShoppingCartId = cart.GetCartId(context); 
        return cart;
    }
     
    public string GetCartId(HttpContextBase context)
    {
        //Pulls cartId from Session
    }

    
    public List<CartItem> GetCartDetials()
    { 
        //Pull cart items from Cache
    }
    //...
}

public class CartItem
{ 
    public string AlbumTitle { get; set; }
    
    public decimal AlbumPrice { get; set; }
    
    public string GenreName { get; set; }
    
    public string ArtistName { get; set; }
    
    public int AlbumId { get; set; }
    
    public int Count { get; set; }
    
    public DateTime DateCreated { get; set; }
    
    public int RecordId { get; set; }
    
    public string CartId { get; set; }
}

Problem
Under normal circumstances, when developing this functionality within a site, its difficult to know whether the internal state of your model matches what you expect. Many different factors can contribute to what is stored, and and the cart summary page usually isn’t tailored to try to inform you about object state.

Solution
Assuming you have read part 1 in the series and had a crack at creating a basic Tab, you are becoming more adventurous and decide that a Glimpse Tab could hold the answer. You decide that to start with, you would like to show the basic content of the cart.

This is what we would like to see:
CartTab

Sample Code
As per usual, the runtime will detect any class in your solution that inherits from ITab. To produce what we have in mind with the awareness that you have access to the API described, the following is how we create your Tab:

public class TabCart : AspNetTab
{
    public override string Name
    {
        get { return "Cart"; }
    }

    public override object GetData(ITabContext context)
    {
        var cart = ShoppingCart.GetCart(context.GetHttpContext());
        var items = cart.GetCartDetials();

        return items;
    }

    public override RuntimeEvent ExecuteOn
    {
        get { return RuntimeEvent.EndSessionAccess; }
    }
}

In this example we have introduced a new concept with the override of ITab.ExecuteOn. This property dictates at what point in the request your Tab will be executed. By default, if you use the base classes Glimpse has, tabs run at the end of the request (RuntimeEvent.EndRequest). But in this case, we need to access a cartId which is stored in Session and in asp.net Session state is only available during the whole request. Hence we want to tap in at the last point which session is available.

Working Sample
If you are interested, here is the link (3a65662aea) to the MVC Music Store sample which has the commit for the above functionality. Feel free to play around with it and modify.

Creating a simple Tab – Your code, your plugins, part 1

When talking about Glimpse and extensions, a lot of attention goes towards the package ecosystem. This contains plugins which provide insights into the various frameworks you use. This makes it very easy to get up and running, and gain deep insights into your application and the systems it’s build on. The barrier to entry is very low and the reward is high, but you still aren’t getting the most out of Glimpse.

With very little effort, it’s possible to have this same instrumentation for the custom code in YOUR application. Image if your application could tell you its current state and give you a picture of logic its executed. What if people working on your project had a full diagnostics console which showed how the custom parts of your application is operating.

This would make dealing with parts of the system you hadn’t built much easier, and provide a much better onramp to those coming to your project for the first time. This woul bring the same level of understanding that you have come to expect from the standard Glimpse packages, right to the custom parts of your application.

For me some examples of what might be possible here are as follows:

  • Show the current state of a custom configuration object in your system
  • Show the content of a shopping cart style of component you might have written
  • Current state of a work flow that you have progressed through
  • Security checks that were conducted to build the page (what passed/failed)
  • etc…

This post is the first in a series of posts looking at your code and your plugins. We will be looking at how Glimpse can be leveraged to show specific details for your system. To start with, we are going to take the first example listed above and see what code it would take to make it work.

Use Case 1: Show the current state of a custom configuration object in your system

In this example, we have a database table called Configuration. The idea is that we want to store information like tax rates and markups in the database so we can update them easily. For this case, we are going to put aside that you could do this via the web.config and focus on the idea.

Existing code
Here is the code that makes up the static Configuration hook mentioned above:

public static class Configuration
{
    public static ConfigurationModel Current { get; set; }
}

public class ConfigurationModel
{
    public string Currency { get; set; }
    
    public double TaxRate { get; set; }
    
    public int DefaultCategory { get; set; }

    public double MarkupRate { get; set; }
}

Problem
Under normal circumstances, we would have very little idea about the state of these object. We could go to the database and query the table directly, but at that point we are assuming that this is the same as what the application has in memory.

In this case, because we aren’t happy with making this assumption and we want to know what we actually have in memory – the thought being:

  • Incase some exception caused only a partial load, or
  • we have some impedance mismatch between the database and the class, or
  • we have some sort of post processor which interprets/modifies the data before populating the object

With our current set of tools, we could set break points in our code so we can manually inspect the object or dump the object out to a log file. Unfortunately, these solutions are time consuming, cumbersome and less than ideal.

Solution
Having heard about Glimpse and used it in other projects, you decide to see if it has anything to offer. You find out that you can easily create Tabs to show arbitrary data. You decide that you would like to see a Tab which shows the state of your Configuration object.

This is what we would like to see:
CustomTab

Sample Code
Creating Tabs within Glimpse is incredibly easy. Once Glimpse has been added to your project, the runtime will detect any class in your solution that inherits from ITab. This process means that there is no configuration xml or registering of classes to get up and running.

This is the only code you would need to give Glimpse the data that you would like to populate your Tab:

public class TabConfiguration : AspNetTab 
{
    public override string Name
    {
        get { return "Setup"; }
    }

    public override object GetData(Glimpse.Core.Extensibility.ITabContext context)
    {
        return MvcMusicStore.Framework.Configuration.Current;
    }
}

Extra Code
For the sake of completeness, here is a trivial example of how you might manually go about populating the Configuration object in the first place (note, this is just one of many):

private void LoadConfiguration()
{
    var connectionString = ConfigurationManager.ConnectionStrings["MusicStoreEntities"];
    var factory = DbProviderFactories.GetFactory(connectionString.ProviderName);
    using (var connection = factory.CreateConnection())
    {
        connection.ConnectionString = connectionString.ConnectionString;
        connection.Open();

        MvcMusicStore.Framework.Configuration.Current = connection.Query<ConfigurationModel>("SELECT * FROM Configuration").First(); 
    }
}

protected void Application_Start()
{
    //...
    LoadConfiguration();
    //...
}

Working Sample
If you are interested, here is the link (4639363cff) to the MVC Music Store sample which has the commit for the above functionality. Feel free to play around with it and modify.