ASP.NET Identity provider in the CMS login

Vote:
 

Hello readers,

I'm working on implementing ASP.NET Identity in an EPiServer project, following this tutorial: http://world.episerver.com/documentation/developer-guides/CMS/security/episerver-aspnetidentity/

In order to create an initial user I made an 'InitializeModule', like this:

[EPiServer.Framework.InitializableModule]
[EPiServer.Framework.ModuleDependency(typeof(EPiServer.Cms.UI.AspNetIdentity.ApplicationSecurityEntityInitialization))]
[EPiServer.Framework.ModuleDependency(typeof(EPiServerUIInitialization))]
public class MyInitializeModule : EPiServer.ServiceLocation.IConfigurableModule
{
    private readonly string[] _roles = new string[] { "WebAdmins", "WebEditors" };

    public void ConfigureContainer(EPiServer.ServiceLocation.ServiceConfigurationContext context)
    {
        //Configure your providers
    }

    public void Initialize(EPiServer.Framework.Initialization.InitializationEngine context)
    {
        //Add initialization logic, this method is called once after CMS has been initialized
        using (UserStore store = new UserStore(new ApplicationDbContext("EPiServerDB")))
        {
            //If there's already a user, then we don't need a seed
            if (store.Users.Any())
                return;

            //We know that this Password hasher is used as it's configured
            IPasswordHasher hasher = new PasswordHasher();
            string passwordHash = hasher.HashPassword( /* obfuscated */);

            ApplicationUser administrator = new ApplicationUser();
            administrator.Email = "martijn.heurter@waternet.nl";
            administrator.EmailConfirmed = true;
            administrator.LockoutEnabled = true;
            administrator.UserName = "Admin";
            administrator.PasswordHash = passwordHash;
            administrator.SecurityStamp = Guid.NewGuid().ToString();

            store.CreateAsync(administrator).GetAwaiter().GetResult();

            //Get the user associated with our username
            ApplicationUser createdUser = store.FindByNameAsync("Admin").GetAwaiter().GetResult();

            IUserRoleStore userRoleStore = store as IUserRoleStore;
            using (var roleStore = new RoleStore(new ApplicationDbContext("EPiServerDB")))
            {
                IList userRoles = userRoleStore.GetRolesAsync(createdUser).GetAwaiter().GetResult();

                foreach (string roleName in this._roles)
                {
                    if (roleStore.FindByNameAsync(roleName).GetAwaiter().GetResult() == null)
                    {
                        roleStore.CreateAsync(new IdentityRole { Name = roleName }).GetAwaiter().GetResult(); ;
                    }

                    if (!userRoles.Contains(roleName))
                        userRoleStore.AddToRoleAsync(createdUser, roleName).GetAwaiter().GetResult();
                }
            }

            store.UpdateAsync(createdUser).GetAwaiter().GetResult();
        }
    }

    public void Uninitialize(EPiServer.Framework.Initialization.InitializationEngine context)
    {
    }
}

I can validate that the user (and roles) get added by looking at the database content.

When I try to login at site-url/episerver and use the credentials for the admin user, it won't let me login.

I have triple-checked the actions described in the blogpost, but I'm sure I've followed the instructions, yet it doesn't work.

Does anyone know how to fix my issue?

Greetings,

Martijn

#176948
Mar 30, 2017 15:05
Vote:
 

Hi Martin

Have you tried creating a clean Alloy site using the Episerver Visual Studio extension? This uses ASP.net Identity by default (and has a controller that sets a new user up if none are configured). 

It may be worth comparing the code against that in the post to see if anything is missing?

David

#176956
Mar 30, 2017 16:54
Vote:
 

Hi Martijn,

Do you need an initialization module or one-time thing?

Perhaps you could create an aspx page (userregistration.aspx) and drop it to the web root:

<%@ Page Language="C#" AutoEventWireup="true" %>
<%@ Import Namespace="EPiServer.ServiceLocation" %>
<%@ Import Namespace="EPiServer.Shell.Security" %>

<%
    string adminRole = "WebAdmins";
    string username = "admin";
    string password = "Administrator123!";
    string email = "noreply@localhost.no";

    var userProvider = ServiceLocator.Current.GetInstance<UIUserProvider>();
    var roleProvider = ServiceLocator.Current.GetInstance<UIRoleProvider>();

    int userCount;
    userProvider.GetAllUsers(0, 1, out userCount);

    if (userCount > 0)
    {
        Response.Write("Database already contains users.");
        return;
    }

    UIUserCreateStatus status;
    var errors = Enumerable.Empty<string>();

    userProvider.CreateUser(username, password, email, string.Empty, string.Empty, true, out status, out errors);
    if (status == UIUserCreateStatus.Success)
    {
        roleProvider.CreateRole(adminRole);
        roleProvider.AddUserToRoles(username, new[] { adminRole });
        Response.Write("Created 'admin' user");
        return;
    }

    Response.Write("Failed to create user");
%>

When you navigate to yourdomain.com/userregistration.aspx, it will check if the database already contains users.

If not, it will create WebAdmins group and a user (username: admin, password: Administrator123!) that is a member of that group.

This aspx file doesn't even have to be included in the project (.csproj) and can be deleted right after the user is created.

#176963
Mar 30, 2017 19:56
Vote:
 
<p>I've discarded the InitializationModule solution and went with the same as the alloy one.</p> <p>Thanks for the help! I managed to get it working after updating all the packages to the latest version.</p>
#176996
Mar 31, 2017 15:41
Vote:
 

Seems like  administrator.IsApproved is set to false as default. I set the property to true and was able to login with this example. 

#178171
Edited, May 03, 2017 15:01
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.