以编程方式在asp.net中启用角色

时间:2014-02-24 21:23:23

标签: asp.net asp.net-mvc-4 visual-studio-2013

我正在尝试使用VS2013在我正在使用的现有ASP.NET(C#,MVC4)项目中添加角色身份验证。

一年前我遇到了一个类似的问题,有一个不同的项目,我设法解决了,但现在我做了完全相同的事情,没有任何反应:Seeding data and creating/managing roles in MVC4 - how hard can it be?

这是我到目前为止所做的:

1。我有自己的DataContext类,它替换了脚手架附带的默认UserContext类:

public class DataContext : DbContext
{
    public DataContext() : base("DefaultConnection")
    {
    }

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

2。在我的初始化类中,我添加了这个:

public class DataContextDbInitializer : DropCreateDatabaseIfModelChanges<DataContext>
{
protected override void Seed(DataContext context)
{
     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);
}

第3。将这些行添加到Global.asax中的Application_Start()方法:

WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
Database.SetInitializer(new DataContextDbInitializer());
DataContext c = new DataContext();
c.Database.Initialize(true);

4。从AccountController中删除了[InitializeSimpleMembership]注释,因此我可以从应用程序生命周期的最开始初始化它(使用App_Start中的WebSecurity.InitializeDatabaseConnection,正如我在3号中所解释的那样)

5。在Web.config中,我将身份验证方法保留为Forms(默认),我的连接字符串如下所示:

  <connectionStrings>
    <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-consultorio;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-consultorio.mdf" providerName="System.Data.SqlClient" />
  </connectionStrings>

在system.web标记内我添加了这个:

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

为了测试一切是否正常,我在一个方法的顶部添加了[Authorize(Roles =“Admins”)]注释,该方法列出了控制器中DB的内容。

  • 如果我像这样运行应用程序并单击使用[Authorize]注释触发方法的链接,我会看到一个登录屏幕。我输入用户“admin”的有效凭据,并重新加载页面而不会抛出任何错误(没有像“错误的用户名”),例外或任何事情。
  • 如果我添加 WebSecurity.InitializeDatabaseConnection(“DefaultConnection”,“UserProfile”,“UserId”,“UserName”,autoCreateTables:true); 作为我的Seed(DataContext context)方法的第一行在我的初始化程序类中(在创建角色的“if”开始之前)我在尝试访问受限制的方法时得到相同的行为(每次输入有效凭据时都会显示登录屏幕并重新加载)。
  • 如果我从Global.asax中的Application_Start方法中删除 WebSecurity.InitializeDatabaseConnection(“DefaultConnection”,“UserProfile”,“UserId”,“UserName”,autoCreateTables:true); 行,那么我尝试登录时获取 System.InvalidOperationException : 它在执行此操作时停止: if(ModelState.IsValid&amp;&amp; WebSecurity.Login(model.UserName,model.Password,persistCookie:model.RememberMe))公共ActionResult登录中( AccountController中的LoginModel模型,字符串returnUrl)方法。 错误消息显示“在调用”WebSecurity“类的任何其他方法之前,必须调用”WebSecurity.InitializeDatabaseConnection“方法。此调用应放在站点根目录中的_AppStart.cshtml文件中。因此,当我从Global.asax中删除该行时,我认为它不喜欢它。 但是我再次添加该行,然后在尝试登录时又回到了重新加载的页面。

问题是什么?

1 个答案:

答案 0 :(得分:1)

好吧,我终于找到了问题,所以我在这里张贴后代(也许一年后我会遇到同样的问题,并会找到我自己的主题!) 代码很好。我只是使用了错误的数据库管理方法:由于我的数据库已经创建(这是我正在添加角色的现有项目),因此从未调用Seed方法,从而将角色放在一边。我只需要切换到DropDatabaseAlways和voilá!