Terminology

Authentication and Authorization in EPiServer CMS

The authentication and authorization system in EPiServer 4.x has been completely replaced and now uses the default membership and role system as introduced in ASP.NET 2.0. See Scott Guthrie's blog for some background information: ASP.NET 2.0 Membership, Roles, Forms Authentication, and Security Resources
For more details on the provider model, see the "Introduction to the Provider Model" section on the following page: http://msdn2.microsoft.com/en-us/asp.net/aa336558.aspx.

Why the Change?

One of the overall design goals of EPiServer is to provide the missing parts in order for web developers to build great Web sites with speed and ease. EPiServer 4.x was based on .NET 1.0 / 1.1 and there was very little support for handling authentication and authorization in those frameworks, therefore we created that part.

With the introduction of ASP.NET 2.0 that piece is already in place and a lot of the new controls and components use the new security infrastructure. Therefore it makes sense for EPiServer to leverage the new official way of doing authentication and authorization.

Advantages of the Provider model

Migration Issues

If you are moving from EPiServer 4 to EPiServer CMS you will have to look out for the following if you are porting code to EPiServer CMS:

Not all characters aare supported when creating names for roles and groups, the characters that are not allowed are: [ ] : | < > + = ; , ? * ' "

Configuration of Authentication and Authorization

Configuration of membership and role providers are done with web.config. Note that if you change providers you may have to revise the security settings (ACL:s) for your entire site, since it is highly likely that user names and role names changes when you switch providers. An example Web.Config section:

<roleManager enabled="true" defaultProvider="WindowsRoleProvider">

  <providers>

    <clear />

    <add name="MultiplexingRoleProvider"

         type="EPiServer.Security.MultiplexingRoleProvider, EPiServer"

         provider1="SqlServerRoleProvider"

         provider2="WindowsRoleProvider"

         providerMap1="SqlServermembershipProvider"

         providerMap2="WindowsMembershipProvider" />

    <add name="WindowsRoleProvider"

         applicationName="EPiServerSample"

         type="EPiServer.Security.WindowsRoleProvider, EPiServer" />

    <add name="SqlServerRoleProvider"

         connectionStringName="EPiServerDB"

         applicationName="EPiServerSample"

         type="System.Web.Security.SqlRoleProvider,

          System.Web, Version=2.0.0.0, Culture=neutral,

          PublicKeyToken=b03f5f7f11d50a3a" />

  </providers>

</roleManager>

 

<membership defaultProvider="WindowsMembershipProvider"

            userIsOnlineTimeWindow="10">

  <providers>

    <clear />

    <add name="MultiplexingMembershipProvider"

         type="EPiServer.Security.MultiplexingMembershipProvider, EPiServer"

         provider1="SqlServerMembershipProvider"

         provider2="WindowsMembershipProvider" />

    <add name="WindowsMembershipProvider"

         type="EPiServer.Security.WindowsMembershipProvider, EPiServer"

         deletePrefix="BUILTIN\" />

    <add name="SqlServerMembershipProvider"

         type="System.Web.Security.SqlMembershipProvider, System.Web,

             Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"

         connectionStringName="EPiServerDB"

         requiresQuestionAndAnswer="false"

         applicationName="EPiServerSample"

         requiresUniqueEmail="true"

         passwordFormat="Hashed"

         maxInvalidPasswordAttempts="5"

         minRequiredPasswordLength="7"

         minRequiredNonalphanumericCharacters="0"

         passwordAttemptWindow="10"

         passwordStrengthRegularExpression="" />

  </providers>

</membership>

The <membership> section controls the membership provider to use. Note that even though there are three providers listed in the <providers> section, only one is active at this time - the WindowsMembershipProvder (controlled by the defaultProvider attribute of the <membership> tag). I.e. the <add ...> lines for MultiplexingMembershipProvider and SqlServerMembershipProvider could be removed without affecting the functionality. There is one exception to this statement - if you have selected the MultiplexingMembershipProvider as the default provider, it will make use of additional providers as defined by the provider<n> attributes.

Similarily the <roleManager> section controls the role provider to use. The same basic principles of defaultProvider / Multiplexing provider as for membership applies here as well.

When you select the provider to use you are deciding which user database that EPiServer authenticates its users against. As previously stated it is possible to change the provider at any time but this may cause problems, forcing you to revise the security settings in EPiServer.

Also note that the membership and role providers are configured separately, but a specific membership provider may require a certain role provider and vice versa. For the current set of providers you must have matching role and membership providers, i.e. if you decide to use WindowsMembershipProvider you must use the WindowsRoleProvider.

Administering security and access rights in EPiServer

When you administer access rights to pages in EPiServer you will use three distinct components that are tied very loosely together. This will cause the UI to show information that may appear confusing. The three components are:

  1. Users (delivered by the current membership provider).
  2. Roles (delivered by the current role provider and the virtual roles).
  3. Access control lists (ACL:s).

An ACL is simply a list of SecurityEntities and an access level. The security entity is a name and information stating if the name represents a role or a user. Once you have a security entity in an ACL, it will not be affected by changes in the membership or role provider. One aspect of this is that when you delete a role and then look at an ACL that had an access entry for this role, the role will still be displayed in the ACL.

Membership providers have API:s for creating, editing and deleting users, but not all providers support updates of the user database. The SQL membership provider allows you to modify the user database, but the Windows membership provider does not. This will be reflected in the UI when you browse users.

NOTE: If you are using the Multiplexing membership provider and want to create users, then the first provider in the multiplexing list (provider1) must support it.
The same applies for role providers.

Virtual Roles

EPiServer CMS introduces an extension of the Role concept called Virtual Roles. These are roles where the membership criteria is determined at runtime for each call to IsInRole. In other words, the virtual role membership is not stored in the database but depends on programmatic criterias.

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

CopyXML
<virtualRoles replacePrincipal="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="Creator" 
        type="EPiServer.Security.CreatorRole, EPiServer" />
    </providers>
</virtualRoles>

The EPiServer.Configuration.VirtualRolesElement.ReplacePrincipal attribute controls wether the current principal object gets replaced with a principal object wrapper that also supports Virtual roles. The current principal object can be accessed in several different ways, the recommended approach is to use EPiServer.Security.PrincipalInfo.CurrentPrincipal , but alternate ways such as System.Web.HttpContext.Current.User are also supported.

If replacePrincipal="false" then virtual roles will only be evaluated when checking access rights based on ACL:s in EPiServer, any principal.IsInRole calls for a virtual role will return false.

The <providers> section 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.

We deliver five virtual roles with EPiServer:

  1. Anonymous
  2. Authenticated
  3. Creator
  4. Everyone
  5. Administrator

In addition to the precreated 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 evaluates to true if the user is member of role1 and role2. This can be used to reduce the number of groups needed for setting the required permissions in EPiServer.

The built-in virtual roles are fairly self-explanatory. The two that may require a bit more in-depth explanations are Administrator and Creator.

Administrator is needed to support localized versions of Windows where the Administrators group has been translated, for example in Swedish Windows versions the Administrators group is named Administratörer. 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.

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

Enterprise Configuration Issues

If you are running in an Enterprise configuration and have a web.config file with multiple site definitions, there are some security related issues you should be aware of.

The membership and role provider definitions cannot be configured on a per-site basis; if you have to have separate provider definitions for each site you cannot share the web.config file. This is a restriction in the Microsoft implementation of ASP.NET 2.0 and not a restrinction in EPiServer CMS.

If you are using the SQl Server membership/role provider and want to use the same set of users / roles for all sites using the same web.config files (probably the most common scenario), you could use a separate database for the user/role information.

  1. Create a new database with the SQL Server management tools.
  2. Prepare the new database with the aspnet_regsql tool (part of the Microsoft .NET Framework) to set up the schema needed for the SQL providers.
  3. Add a new connection string to the <connectionStrings> section in web.config (it may be placed in a separate connectionStrings.config file) that points to the newly created database.
  4. Change the connectionStringName attributes of the SqlMembershipProvider and SqlRoleProvider to point to the connection string added in step 3.

See Also

ASP.NET 2.0 Membership, Roles, Forms Authentication, and Security Resources
http://msdn2.microsoft.com/en-us/asp.net/aa336558.aspx - "Introduction to the Provider Model".
System.Web.UI.WebControls.Login
System.Web.UI.WebControls.LoginView
EPiServer.Security.PrincipalInfo
System.Web.HttpContext.User
Security Overview on msdn.com