This content is archived. See latest version here.

Last updated: Mar 31 2014

EPiServer CMS uses an extension of the Role concept called Virtual Roles. These are roles where the membership criteria is determined at runtime. In other words, the virtual role membership is not stored in the database, but depends on programmatic criteria that can vary between each request.

How it works

Virtual roles are controlled by the <virtualRoles> configuration element in the <episever.framework> section in web.config. A typical configuration looks like this:

XML
<virtualRoles addClaims="true">
   <providers>
      <add name="Administrators" type="EPiServer.Security.WindowsAdministratorsRole, EPiServer" />
      <add name="Everyone" type="EPiServer.Security.EveryoneRole, EPiServer" />
      <add name="Authenticated" type="EPiServer.Security.AuthenticatedRole, EPiServer" />
      <add name="Anonymous" type="EPiServer.Security.AnonymousRole, EPiServer" />
      <add name="PackagingAdmins" type="EPiServer.Security.MappedRole, EPiServer.Framework" roles="WebAdmins, Administrators" mode="Any" />
      <add name="CmsAdmins" type="EPiServer.Security.MappedRole, EPiServer" roles="WebAdmins, Administrators" mode="Any" />
      <add name="CmsEditors" type="EPiServer.Security.MappedRole, EPiServer" roles="WebEditors" mode="Any" />
      <add name="Creator" type="EPiServer.Security.CreatorRole, EPiServer" />
  </providers>
</virtualRoles>

Virtual roles can operate in two modes. By default the addClaims attribute sets whether a claim is added to the current principal for each virtual role that a user is member of. If instead replacePrincipal is set to true then the principal object gets replaced with a principal object wrapper that supports virtual roles by overriding the IsInRole-method, this mode is not supported with federated security or other scenarios where claims are used since the wrapper is not claims-aware.

The current principal object can be accessed in several different ways. The recommended approach is to use EPiServer.Security.PrincipalInfo.CurrentPrincipal property, but alternate ways such as System.Web.HttpContext.Current.User at Microsoft MSDN are also supported.

If both replacePrincipal="false" and addClaims="false" then virtual roles will only be evaluated when checking access rights based on ACLs in EPiServer CMS. Any principal.IsInRole calls for a virtual role will return false.

The <providers> element contains a series of <add...> tags. Each <add...> defines a virtual role implementation (as identified by the type attribute) and gives the role a name with the name attribute.

The following virtual roles are delivered with EPiServer CMS:

  • Anonymous
  • Authenticated
  • Creator
  • Everyone
  • Administrator
  • CmsAdmins
  • CmsEditors
  • PackagingAdmins

In addition to the predefined roles, it is very easy to create new virtual roles to allow access based on business rules, such as only allow access during business hours. A common scenario is to define virtual roles that evaluate to true if the user is a member of role1 and role2. This can be used to reduce the number of groups needed for setting the required permissions in EPiServer CMS.

Administrator is needed to support localized versions of Windows, where the Administrators group has been translated. The Administrators virtual role will do a localization-independent test for the Administrators group, thus eliminating the need to manually modify web.config or access rights in EPiServer CMS

Creator is only used when evaluating AccessControlLists in EPiServer CMS and it will return true if the current principal is the same as the Creator for an ACL.

PackagingAdmins is used for controlling access to the Add-ons menu option from where add-ons are managed.

The PackagingAdmins, CmsAdmins and CmsEditors virtual roles are of the MappedRole type (MappedRole is used to map existent or non-existent groups to several other groups). The roles attribute contains the names of one or more roles that are used to evaluate membership in the MappedRole. The mode attribute can have the following values:

  • Any means that membership in at least one of the roles listed in the roles attribute is required for membership in the mapped role.
  • All means that membership in all of the roles listed in the roles attribute is required for membership in the mapped role.

Registering virtual roles programmatically

It is also possible to register virtual roles programmatically:

[InitializableModule]
[ModuleDependency((typeof(EPiServer.Web.InitializationModule)))]
public class VirtualRoleInitializer : IInitializableModule
{
    public void Initialize(InitializationEngine context)
    {
        var virtualRoleRepository = VirtualRoleRepository<VirtualRoleProviderBase>.GetDefault();
        virtualRoleRepository.Register("MyVirtualRoleType", new MyVirtualRoleType());
    }

    public void Uninitialize(InitializationEngine context) { }
    public void Preload(string[] parameters) { }
}

Comments