If you go into admin in EPiServer and then "Set Access Rights for", you will fail to choose your Identity 2.0 roles. Reason for this is that the Access Rights GUI in EPiServer are closely connected to the old membership provider, which you disable when you implement the ASP.NET Identity.
Edit:
As Per suggested in the comment field, it's also possible to to implement this using built in provider instead of using StructureMap. So by add the following code in web.config and add the IdentitySecurityEntityProvider.cs to the project it will also work. Thanks :-)
<episerver.framework>
<securityEntity>
<providers>
<add name="IdentityProvider" type="TestSite.Business.AccessRights.IdentitySecurityEntityProvider, TestSite" />
</providers>
</securityEntity>
<appData basePath="App_Data" />
<scanAssembly forceBinFolderScan="true" />
<virtualRoles addClaims="true">
<providers>
Solution
First you need to setup the DI/IOC to override the “SecurityEntityProvider” and replace it with “IdentitySecurityEntityProvider” class. The setup below show how to do that.
ServiceLocationConfiguration.cs
using System;
using EPiServer.Security;
using StructureMap;
using TestSite.Business.AccessRights;
namespace TestSite.Business.ServiceLocation
{
public static class ServiceLocationConfiguration
{
public static Action<ConfigurationExpression> Current
{
get
{
return configuration =>
{
configuration.For<SecurityEntityProvider>().Use(() => new IdentitySecurityEntityProvider());
};
}
}
}
}
DependenciesInitializationModule.cs
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.ServiceLocation;
namespace TestSite.Business.ServiceLocation
{
[InitializableModule]
[ModuleDependency(typeof(ServiceContainerInitialization))]
public class DependenciesInitializationModule : IConfigurableModule
{
public void Initialize(InitializationEngine context)
{
}
public void Preload(string[] parameters) { }
public void Uninitialize(InitializationEngine context)
{
//Add uninitialization logic
}
public void ConfigureContainer(ServiceConfigurationContext context)
{
context.Container.Configure(ServiceLocationConfiguration.Current);
}
}
}
Disclaimer: The code isn't tested on large database with a lot of users and groups.
IdentitySecurityEntityProvider.cs
using System;
using System.Collections.Generic;
using System.Linq;
using EPiServer.Security;
using TestSite.Models.Account;
namespace TestSite.Business.AccessRights
{
public class IdentitySecurityEntityProvider : PagingSupportingSecurityEntityProvider
{
private readonly ApplicationDbContext _db = new ApplicationDbContext();
public override IEnumerable<string> GetRolesForUser(string userName)
{
var theUser = _db.Users.FirstOrDefault(u => u.UserName.Equals(userName, StringComparison.CurrentCultureIgnoreCase));
return theUser == null ? Enumerable.Empty<string>() : theUser.Roles.Select(role => _db.Roles.Find(role.RoleId).Name.ToString()).AsEnumerable();
}
public override IEnumerable<SecurityEntity> Search(string partOfValue, string claimType)
{
int totalCount;
return this.Search(partOfValue, claimType, 0, int.MaxValue, out totalCount);
}
public override IEnumerable<SecurityEntity> Search(string partOfValue, string claimType, int startIndex, int maxRows, out int totalCount)
{
totalCount = 0;
switch (claimType)
{
case "http://schemas.microsoft.com/ws/2008/06/identity/claims/role":
return this.SearchRoles(partOfValue, startIndex, maxRows, out totalCount);
case "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name":
case "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier":
return this.SearchUsers(partOfValue, startIndex, maxRows, out totalCount);
case "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress":
if (!string.IsNullOrEmpty(partOfValue))
return this.SearchEmails(partOfValue, startIndex, maxRows, out totalCount);
else
return Enumerable.Empty<SecurityEntity>();
default:
return Enumerable.Empty<SecurityEntity>();
}
}
private IEnumerable<SecurityEntity> SearchEmails(string partOfName, int startIndex, int maxRows, out int totalCount)
{
var usersList = _db.Users.ToList();
var users = usersList.Where(a => a.Email != null && a.Email.ToLower().Contains(partOfName.ToLower())).ToList();
var entityList = users.Select(user => new SecurityEntity(user.Email)).ToList();
totalCount = entityList.Count;
return entityList;
}
private IEnumerable<SecurityEntity> SearchUsers(string partOfName, int startIndex, int maxRows, out int totalCount)
{
totalCount = 0;
if (_db.Users == null) return Enumerable.Empty<SecurityEntity>();
var usersList = _db.Users.ToList();
var entityList = !string.IsNullOrEmpty(partOfName) ? usersList.Where(a => a.UserName.ToLower().Contains(partOfName.ToLower())).ToList().Select(user => new SecurityEntity(user.UserName)).ToList() : usersList.Select(user => new SecurityEntity(user.UserName)).ToList();
totalCount = entityList.Count;
return entityList;
}
private IEnumerable<SecurityEntity> SearchRoles(string partOfName, int startIndex, int maxRows, out int totalCount)
{
totalCount = 0;
if (_db.Roles == null) return Enumerable.Empty<SecurityEntity>();
var rolesList = _db.Roles.ToList();
var roles = rolesList.Where(a => a.Name.ToLower().Contains(partOfName.ToLower())).ToList();
var entityList = roles.Select(role => new SecurityEntity(role.Name)).ToList();
totalCount = entityList.Count;
return entityList;
}
}
}
<location path="EPiServer/CMS/admin">
<system.web>
<authorization>
<allow roles="WebAdmins, Administrators, CustomGroup" />
<deny users="*" />
</authorization>
</system.web>
</location>
Then you
can click add “Users/ group button” in the “Set Access rights” module. Choose
users or group and then add it with the green arrows and click OK.