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
In the last part I covered off how we used Specflow to create a series of executable specifications to described the desired behaviour of the licensing framework – but we didn't touch upon and of the implementation details. Essentially there are 5 main parts to the licensing framework:
A Private Key.
A Public Key, generated from the Private Key:
The License, cryptographically signed using SHA256, to ensure it's tamper proof:
License Validation Rules which are used to examine the license and determine whether it's valid for any given set of conditions:
And finally, the License Validator, which takes in a client license, the public key and the list of validation rules and then performs the validation, if the license is invalid, exceptions are thrown detailing the ways in which the license is invalid:
To generate a license 3 steps are required:
- You need to create your
LicenseCriteria– this is the domain object that contains the details of the license; the id, issue date, expiration date, license type and any custom metadata you wish to add.
- A Private Key is required. This is generated by the
PrivateKeyProvider, which can also be used to recreate the private key from a string – a useful scenario as you'll want to generate the private key once per major version of your application, store it in string form in a repository of some kind, and rehydrate it when you need to generate a new license.
- Finally, you need to pass the
LicenseCriteriaand the Private Key to the
ServerLicenseGenerate, which will use these two inputs to create a
ServerLicense, which is an object that contains the Public Key, Private Key, License Criteria and License – it's an object you would most likely want to store against the user for a full audit trail of the license created for them.
The code snippet below shows how how to generate a Public Key and License and write them out to the file system:
Validating a license is also a straight forward process. The first step requires us to retrieve the Public Key and License we generated in the previous step, can pass that to a helper method which performs the validation:
Next we need to rehydrate the Public Key and Client License back into domain objects, then we need to specify the collection of
ILicenseValidationRule we are going to use to validate the license. The final step is to pass in the ClientLicense, Public Key and license validation rules into the
LicenseValidator to perform the validation. If the license validates the
Validate() method will return, if there are any problems either a
AggregateException containing a collection of
LicenseViolationException will be thrown. The majority of the code in the snippet below performs the error handling and conversion of exceptions into messages that can be shown to the user:
In the next part of the series, I'll take you through a step by step guide for implementing custom validation logic.