We've open sourced a lightweight licensing framework we've been using internally over the last couple of years. In a 5 part series I'm covering the motivation behind building it, how you can use it, how you can extend it for your own scenarios and how you could use it in a real world situation:
- Part 1: Why build another licensing system?
- Part 2: Defining the desired behaviour
- Part 3: How to create and validate a license
- Part 4: How to implement custom validation logic
- Part 5: Real world usage patterns
Over the last two years we've been developing an Azure based Content Management System called Vellum; in addition to a consumer-facing SaaS offering we wanted to allow developers (in particular other Microsoft Partners) to purchase and use the platform in a more traditional manner. In order to achieve this we wanted to add a simple licensing mechanism that would help persuade users to do the right thing and pay for the product.
In the past we've implemented licensing via commercial products such as CryptoLicensing (which is great and flexible platform) for desktop applications, but it didn't quite fit a web application. The next framework we looked at was Rhino.Licensing, an excellent & elegant framework based on creating a SHA256 cryptographic signature for an XML document which allows you to check to see if the message has been tampered with. The framework is quite mature (as it's obviously used in all Hibernating Rhinos products); and has many useful features for desktop applications; the ability to generate licenses that are locked to a specific machine (so that the license can't be transferred or sold on), embed other data into the license, and a floating license mechanism. There is also a great admin tool that enables you to easily generate licenses. There are several great articles about the inner workings of Rhino.Licensing including this how-to guide by James Gregory and this code whittling kata by Patrick Lioi; both are worth your time.
I'm not a big fan of reinventing the wheel or the Not Invented Here syndrome, but Rhino.Licensing didn't quite fit our requirements & after doing a complete code review there were a number of design decisions & implementation details that meant we couldn't use it without making some significant changes to the codebase. Top of the list was to separate the concerns of license generation and license validation, next was to create extensibility points to make it very easy to build custom license validation rules, followed by decoupling license generation & validation from license storage and retrieval. The final point was to replace "magic string" based passing of licenses into a more concretely defined set of types to make the API easier to use. So, inspired by the code whittling notion and wanting a new "commuting project" to occupy my 2 x 1 hour daily train commute I decided to attempt to write a licensing framework that would meet our needs.
In the next post I'll cover how we used Behaviour Driven Development (BDD) via Specflow to elaborate the desired behaviour we wanted the licensing framework. If you want to see code, skip to Part 3, which contains a code walkthrough.