I am virtually in the role, dude

UPDATE 2009-11-02: This code for this project has now been moved to CodePlex.

Sometimes I wonder if anyone else knows that special feeling. The feeling you have when fingers just start itching and you know you just have to get that great idea out which has slowly worked it’s way all the way from the back of your head down to your fingertips. That special feeling when you just have to create yet another EPiServer CMS plug-in.

This time I decided to explore the wonderful world of virtual roles – and create a sample pack with a few useful roles. This connects back to me digging personalization these days – and using roles (especially virtual ones) is one way of approaching it. So in a couple of hours last night I threw this small library together with a bunch of hopefully useful virtual roles. This is what it contains:

This is a role that will allow you to filter on the Remote IP, remote host, Url Referer and user agent – and only if the current request matches your filters, will the user be in that role.
You define it in web.config in the <virtualRoles> section like this:

<add name="LocalOnly" type="EPiServer.Research.VirtualRoles.RemoteFilterRole, VirtualRolesSamplePack" ip=""/>

In this case it filters on the IP address, to ensure that only local requests will be in that role. It will appear in edit/admin mode as any other role, with the name you provide (in this case “LocalOnly”). The filter parameters you can add in web.config are:

  • “ip”. If set, the Remote IP should contain this string. Useful if you want to make sure that all your employees automatically have access to internal information as long as they access it from a company computer. Note that IP’s look a lot differently when you use IPv6.
  • “host”. If set, the Remote Host should contain this string. E.g. “.dk” would ensure that only visitors from a resolved hostname of “.dk” would be in the role.
  • “agent”. If set, the User agent should contain this string. In case there’s a page you only want cell-phone users, or Firefox browsers to see :-)
  • “referer”. If set, the referring url should contain this string. This could be useful if you have a piece of role based content that contains information you want to direct to people coming straight from google for instance.

If more than one filter is set, an implicit AND will be applied between them, e.g. the request needs to meet all the demands.


The TimedRole is a role that allows you to setup a daily interval where the user will belong to that role. Let’s imagine that you only want editors to be able to publish new content between 9 and 5. Then you simply make sure that the Publish permission is only granted to this role (perhaps in combination with another role).

<add name="Daytime" type="EPiServer.Research.VirtualRoles.TimedRole, VirtualRolesSamplePack" start="09:00:00" stop="17:00:00"/>

Parameters are “start” and “stop”. HH:MM:SS works, if you try another time format it’ll try to figure it out – but no promises.


Sometimes randomness can be a good thing :-) This role will randomly decide if the current user is in the role or not. Can be useful for A/B testing or to decide whether you want to bore your users with a pop-up evaluation form, banner ad or similar.
It’s also a great way to annoy your users and can produce funny bug-reports “I don’t get it – the page was there just a moment ago”

<add name="RandomRole" type="EPiServer.Research.VirtualRoles.RandomRole, VirtualRolesSamplePack" pctinrole="80"/>

Parameter here is “pctinrole” and it’ll set the percentage of times it should return that the user is in the role.


The user will be in this role when he makes his first request, the very first time he visits the website. Once it has been checked it sets a cookie that causes it never to be true again – until the cookie has been cleared at least. No parameters.

<add name="FirstTime" type="EPiServer.Research.VirtualRoles.FirstTimeVisitor, VirtualRolesSamplePack"/>


This might seem a bit odd, but in some cases it can be quite useful to have a role that will tell you when a user is not in another role. For instance you don’t want to bother super users with content intended for newbies. So, you simple make a NotSuperUser role using this role provider.

<add name="NotAdmin" type="EPiServer.Research.VirtualRoles.NotInRole, VirtualRolesSamplePack" role="Administrators"/>

As you see, only one parameter, “role” which should be the name of the role the user shouldn’t be in to be in this one :-)


So, you’ve defined all the roles you need in your web.config – but now comes the tricky part – sometimes you need to combine them. For instance, you might want to ensure that only people in the webmaster AD group, working from a company computer within working hours are allowed to publish new pages. Or maybe you want to display a popup website evaluation poll to random anonymous users who are not visiting the site for the first time? This is where the MultiRole comes into play. It takes a comma-separated list of role names and ensures that the user has to belong to every single one of those roles for him to belong to this one as well. Or, by flipping a switch the user just needs to belong to one of the listed roles to be in this one (AND vs OR).

<add name="LocalDayAdminAuthenticated" type="EPiServer.Research.VirtualRoles.MultiRole, VirtualRolesSamplePack" roles="Administrators,Authenticated,LocalOnly,Daytime" mode="all"/>

Parameters: “roles” a comma separated list of roles. “mode” can be “any” or “all”, meaning belonging to any of the roles or all of the roles. Default is “all”.


I highly recommend using this together with RoleBasedContents – that way you can achieve quite a high degree of personalization without much effort.

If you think of more useful roles, leave a comment. When this library matures I might just put it on codeplex / epicode so it’ll be open for further additions.

Until then, you can download it here. Full source can be downloaded here. Tested against EPiServer CMS 5 R2 SP1, but should also work with SP2. I see no reason why it shouldn’t compile / work with older version 5’s as well.

Post Comments()