【问题标题】:How exactly do I use Roles in Asp.NET MVC 4?我究竟如何在 Asp.NET MVC 4 中使用角色?
【发布时间】:2013-01-09 17:34:43
【问题描述】:

我已经阅读了大量的文章和论坛,但我仍然无法弄清楚...... 我正在使用 Visual Studio Express 2012 for Web 和 MVC4+Razor+Entity Framework CodeFirst 构建一个 Internet 应用程序。

据我了解,在 MVC4 中使用 SimpleMembership 管理用户和角色比以前的版本更简单,应该相当简单。

在我的应用程序中,我只需要授权某些用户组(例如,只有管理员可以访问某些页面)。我知道这是通过将参数传递给 [Authorize] 注释来实现的:[Authorize(Roles="Admins")] 但是如何创建这些角色以及如何向它们添加用户?

为了要求身份验证,我在控制器方法顶部添加了注释 [Authorize](不带参数),它无需进行任何额外配置或添加任何其他内容即可工作。此外,当我查看自动创建的数据库时,我看到了一个名为 pages_UsersInRoles 的表,其中包含 UserId 和 RoleId 列。所有这一切让我觉得这必须是一个非常简单的任务,因为一切似乎都已设置并准备好使用,但我就是不知道如何;)

到目前为止,我尝试过的(但没有成功)是这样的: 我有一个继承自 DropCreateDatabaseIfModelChanges 的“DataContextDbInitializer”类。 Seed 方法在该类中被覆盖,我添加了这个(我必须导入 System.Web.Security):

Membership.CreateUser("user1", "123456");
Roles.CreateRole("Admins");
Roles.AddUserToRole("user1", "Admins");

我还在 Web.config 文件的标签中插入了这个标签:

<roleManager
enabled="true"
cacheRolesInCookie="true" >
</roleManager>

为了尝试一下,我在控制器中的操作方法顶部添加了 [Authorize(Roles="Admins")],然后以“admin”身份登录并尝试访问该方法,但没有运气:(

我不知道我还缺少什么... 如果有人能指导我完成这件事,我会非常高兴,因为它让我发疯:P

谢谢!

【问题讨论】:

  • 你看到这篇文章了吗? weblogs.asp.net/scottgu/pages/…
  • 谢谢 :) 但是那篇文章使用的是以前版本的 ASP.NET,并且基于 Windows 身份验证,而不是使用 Forms 的 Internet 应用程序。这就是我阅读的所有内容的问题:它都已经过时并且混合了太多东西而不是直截了当:(

标签: asp.net-mvc-4 visual-studio-2012 roles membership


【解决方案1】:

我的猜测是您的 Seed 方法没有被调用。通过在方法中放置一个断点并在调试器中运行它来验证它是否被调用。除非您对应用程序进行了一些其他更改,否则不会使用 EF 迁移。默认情况下,数据库使用 InitializeSimpleMembershipAttribute 进行初始化。您将看到该属性已添加到 Account Controller 中,如下面的代码所示。

[Authorize]
[InitializeSimpleMembership]
public class AccountController : Controller
{
  ....
}

这种方式只有在 AccountController 被访问时才会被调用。您将在 Filters\InitializeSimpleMembershipAttribute.cs 中找到定义。下面是这个类的一个代码 sn-p,它可能是为什么它没有被调用的线索。

// Create the SimpleMembership database without Entity Framework migration schema
((IObjectContextAdapter)context).ObjectContext.CreateDatabase();

InitializeSimpleMembershipAttribute 中的许多代码用于处理未将表单身份验证用于 MVC 应用程序的情况。如果您将始终使用表单身份验证,则可以消除此代码并自己初始化数据库。只需从 AccountController 中删除此属性并将您自己的初始化代码放入 Global.asax Application_Start 方法中。您可以在 Application_Start 方法中添加类似的内容

Database.SetInitializer<UsersContext>(new MyDBInitializer());

Seed 方法如下所示

WebSecurity.InitializeDatabaseConnection("DefaultConnection",
      "UserProfile", "UserId", "UserName", autoCreateTables: true);

var roles = (SimpleRoleProvider)Roles.Provider;
var membership = (SimpleMembershipProvider)Membership.Provider;

if (!roles.RoleExists("Admin"))
{
     roles.CreateRole("Admin");
}
if (membership.GetUser("user1", false) == null)
{
     membership.CreateUserAndAccount("user1", "123456");
}
if (!roles.GetRolesForUser("user1").Contains("Admin"))
{
    roles.AddUsersToRoles(new[] { "user1" }, new[] { "Admin" });
} 

请注意,您需要通过调用 WebSecurity.InitializeDatabaseConnection 方法在 Seed 方法中初始化 Web 矩阵安全数据库。

您可以在此blog post 中找到有关播种 SimpleMembership 的更多详细信息,其中包括示例项目的完整源代码。

【讨论】:

  • 感谢您的精彩解释 :) 但是,我仍然无法让它工作......我在 About() 方法的顶部添加了 [Authorize(Roles = "Admins")] Home 控制器,当我尝试访问它时,我一直被要求登录。可能用户没有被确认为“管理员”角色的一部分,但我仍然不知道为什么。
  • 我在最后更新了答案,并附上了指向博客文章的链接。这篇博文提供了有关如何为 SimpleMembership 播种的更详细说明,并提供了完整的源代码供下载。
【解决方案2】:

最后,我成功地完成了整个工作!

我的种子方法现在看起来像这样:

WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);

if (!Roles.RoleExists("Admins"))
{
    Roles.CreateRole("Admins");
}
if (!WebSecurity.UserExists("admin"))
{
    WebSecurity.CreateUserAndAccount("admin", "123456");
}
if (!Roles.GetRolesForUser("admin").Contains("Admins"))
{
    Roles.AddUsersToRoles(new[] { "admin" }, new[] { "Admins" });
}
base.Seed(context);

我在 Global.asax 中的 App_Start 如下所示:

Database.SetInitializer(new DataContextDbInitializer());
DataContext c = new DataContext();
c.Database.Initialize(true);

我不确定这是否真的在做某事,但我在 Web.config 的 system.web 标记中有这个:

<roleManager enabled="true" cacheRolesInCookie="true" />

我还从 AccountController 中删除了 [InitializeSimpleMembership],并在 AccountModels 中删除了 UsersContext 类。我将这一点移到了我自己的上下文类中:

public DbSet<UserProfile> UserProfiles { get; set; }

然后,为了测试一切是否正常,我在 HomeController 的 About() 方法之上使用了 [Authorize(Roles = "Admins")] 注释。如果一切正常,这将迫使我以 admin/123456 身份登录,以便能够看到由 HomeController/About 控制的“About”页面。哪个;)

【讨论】:

  • 这与我的回答有何不同。 :(
  • 我不太清楚,但可能是 Database.SetInitializer 位?我知道这是最不同的地方......但是,你的回答也帮助了我,所以谢谢:) 我没有足够的声誉来投票给你。
  • @PatriciaMiguel 你不得不接受凯文的回答,因为你的回答和他很相似
猜你喜欢
  • 2014-08-03
  • 1970-01-01
  • 1970-01-01
  • 2019-08-21
  • 2010-09-07
  • 1970-01-01
  • 2018-10-09
  • 2015-09-05
  • 1970-01-01
相关资源
最近更新 更多