如何为MVC .Net Core应用程序创建单个管理员用户

5
我正在构建一个网络应用程序,它本质上是一家商店。但我想为网站管理员提供一种简单的方式添加新产品。然而,我希望限制网站的这部分仅供管理员访问。目前我不需要其他用户使用此功能。
如何使任何具有管理员用户名和密码的人都可以访问这些页面,并且它将保持知道他们已经登录?我已经建立了一个系统,接受用户输入,如果正确就继续进入管理员页面。但问题是,如果有人决定直接访问Admin/AddProduct等页面,我的应用程序需要知道他们不能访问AddProduct页面,并将他们重定向回登录页面。

你需要在你的登录中添加某种权限系统。对于asp.net,你可以使用asp.net身份认证框架 - Mats391
好的,我已经研究过了,但是我不明白如何将我的单个管理员用户添加到它正在提取的任何数据库中。我根本不想有注册用户链接。 - Joe Higley
在启动时,您可以检查管理员用户是否存在,如果不存在,则创建它。您只需要使用注册示例中使用的相同方法,并使用您想要的值来调用它即可。 - Mats391
这是否只会创建一个实例。由于这是一个Web应用程序,我的担忧是每次有人访问该网站时,它不会调用启动并创建大量相同的管理员用户。 - Joe Higley
在创建用户之前,您可以检查该用户是否已存在。 - Mats391
2个回答

20
你可以通过在你的Startup类中创建一个CreateRoles方法来轻松实现这一点。这有助于检查角色是否已创建,并在应用程序启动时创建角色(如果尚未创建)。就像这样:
private async Task CreateRoles(IServiceProvider serviceProvider)
{
    //initializing custom roles 
    var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
    var UserManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
    string[] roleNames = { "Admin", "Store-Manager", "Member" };
    IdentityResult roleResult;

    foreach (var roleName in roleNames)
    {
        var roleExist = await RoleManager.RoleExistsAsync(roleName);
        // ensure that the role does not exist
        if (!roleExist)
        {
            //create the roles and seed them to the database: 
            roleResult = await RoleManager.CreateAsync(new IdentityRole(roleName));
        }
    }

    // find the user with the admin email 
    var _user = await UserManager.FindByEmailAsync("admin@email.com");

   // check if the user exists
   if(_user == null)
   {
        //Here you could create the super admin who will maintain the web app
        var poweruser = new ApplicationUser
        {
            UserName = "Admin",
            Email = "admin@email.com",
        };
        string adminPassword = "p@$$w0rd";

        var createPowerUser = await UserManager.CreateAsync(poweruser, adminPassword);
        if (createPowerUser.Succeeded)
        {
            //here we tie the new user to the role
            await UserManager.AddToRoleAsync(poweruser, "Admin");

        }
   }
}

然后你可以在Startup类的Configure方法中调用await CreateRoles(serviceProvider);方法。确保Configure类中有IServiceProvider作为参数。
问题2:如何使任何具有管理员用户名和密码的人都可以访问这些页面?
答案2:您可以轻松地做到这一点,就像这样:
[Authorize(Roles="Admin")]
public class ManageController : Controller
{
   //....
   Return View();
}

您还可以在操作方法中使用基于角色的授权。如果需要,可以分配多个角色:
[Authorize(Roles="Admin")]
public IActionResult Index()
{
/*
 .....
 */ 
}

虽然这样做可以正常工作,但为了更好的实践,你可能想要了解如何使用基于策略的角色检查。你可以在ASP.NET Core文档这里找到相关信息,或者阅读我写的这篇文章这里

这个方法很好用,我一定会将其标记为答案,但是我有一个问题。由于某种原因,如果用户名和电子邮件不是相同的值,它就无法接受我的登录。例如:{UserName =“Joe@gmail.com”,Email =“Joe@gmail.com”}可以使用电子邮件和密码登录,但{UserName =“Admin”,Email =“Joe@gmail.com”}在尝试使用电子邮件和密码登录时返回无效登录。 - Joe Higley
我找到了解决方法。显然创建默认的 AccountController 登录操作的人没有注意到 SignInPasswordAsync 使用的是用户名和密码而不是电子邮件和密码。我不得不更改它,还要通过删除依赖属性“EmailAddress”来更改 LoginViewModel。 - Joe Higley
1
请确保在Configure类中将IServiceProvider作为参数。你能给个例子吗?1. 在默认的ASP.NET Core启动中,没有Configure类;2. 默认注入的是IServiceCollection services - Lei Yang

5

一旦您将ASP.NET身份验证添加到项目中,您可以在应用程序中实现基于角色的授权(Role-based Authorization)。基本上,它允许您为仅限管理员用户可用的控制器设置[Authorize(Roles = "Administrator")]属性。


2
使用角色是一种不鼓励且过时的概念。您应该使用基于策略的授权,其中“角色”被视为声明来处理,因为它比角色更灵活。 - Tseng
1
同意,但对于问题中描述的简单场景,基于角色的授权可能更为直接。将来可以轻松迁移到基于策略的授权。 - Alexey Andrushkevich
如何在我的项目中添加身份验证? - Joe Higley
请点击这里 - Alexey Andrushkevich

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接