我使用 ASP.NET MVC5 创建了一个新应用程序,使用个人用户帐户来确保安全,并使用代码优先迁移来进行模型/数据库建模。所有选项都是默认的。
我想为它设置自定义用户和角色,所以我使用 RoleManager
和 UserManager
创建了一个种子来填充数据库。它工作正常,创建 3 个用户、3 个角色并正确设置每个用户的角色。
我可以正确登录应用程序。问题是我无法使用
User,这是登录的用户,我唯一能得到的是 User.Identity.IsAuthenticated
值和 User.Identity.Name
,它们是正确的。 Roles.GetRolesForUser("John")
或 User.IsInRole("Student")
等所有其他方法总是会生成此异常:
ProviderException : The Role Manager feature has not been enabled.
好吧,就像在 this article 中一样,我设法将 <roleManager enabled="true" />
插入到 Web.config 中,现在需要很长时间才能响应,并生成如下异常:
指的是:
Roles.IsUserInRole("Student")
生成:
HttpException
指的是:
Roles.GetRolesForUser(User.Identity.Name)
生成:
NullReferenceException
以学生角色登录的用户访问“关于”页面:
[Authorize(Roles="Teacher")]
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
生成:
SqlException
HttpException
就好像我根本没有连接到数据库,这是自动生成的 LocalDB,我可以填充种子方法,甚至可以登录到应用程序。
我什至可以使用以下代码从 AspNetUsers 表加载数据并在 View 中显示它:
using (Models.ApplicationDbContext db = new Models.ApplicationDbContext())
{
List<Models.ApplicationUser> Users = db.Users.ToList();
ViewBag.Users = Users;
}
return View();
请帮忙:'(
这是种子代码,工作正常,因此它可以使用身份引擎连接到数据库。
protected override void Seed(LocalBDAuthTest.Models.ApplicationDbContext context)
{
#region Create Roles Student, Teacher e Administrator
var RoleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
// Student
if (!RoleManager.RoleExists("Student"))
{
RoleManager.Create(new IdentityRole("Student"));
}
// Teacher
if (!RoleManager.RoleExists("Teacher"))
{
RoleManager.Create(new IdentityRole("Teacher"));
}
// Administrator
if (!RoleManager.RoleExists("Administrator"))
{
RoleManager.Create(new IdentityRole("Administrator"));
}
#endregion
#region Create Users for Student, Teacher e Administrator Roles.
var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
// Create a Student user and set it's role to Student
if (!context.Users.Any(u => u.UserName == "John"))
{
var Student = new ApplicationUser() { UserName = "John" };
var Result = UserManager.Create(Student, "123456");
}
if (!UserManager.FindByName("John").Roles.Any())
{
UserManager.AddToRole(UserManager.FindByName("John").Id, "Student");
}
// Create a Teacher user and set it's role to Teacher
if (!context.Users.Any(u => u.UserName == "Arnold"))
{
var Teacher = new ApplicationUser() { UserName = "Arnold" };
var Result = UserManager.Create(Teacher, "123456");
UserManager.AddToRole(Teacher.Id, "Teacher");
}
if (!UserManager.FindByName("Arnold").Roles.Any())
{
UserManager.AddToRole(UserManager.FindByName("Arnold").Id, "Teacher");
}
// Create a Administrator user and set it's role to Administrator
if (!context.Users.Any(u => u.UserName == "Caroline"))
{
var Administrator = new ApplicationUser() { UserName = "Caroline" };
var Result = UserManager.Create(Administrator, "123456");
UserManager.AddToRole(Administrator.Id, "Administrator");
}
if (!UserManager.FindByName("Caroline").Roles.Any())
{
UserManager.AddToRole(UserManager.FindByName("Caroline").Id, "Administrator");
}
#endregion
}
最佳答案
这是由于混合了 ASP.NET Identity 和 ASP.NET Membership,这样做了:
<system.web>
<roleManager enabled="true" />
</system.web>
您启用了成员资格 SqlRoleProvider
,它使用网站\app_dir 文件夹中数据库中默认 SQL Express 实例中的角色存储。
如果您打开 machine.config,您会发现:
<connectionStrings>
<add name="LocalSqlServer"
connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;
AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
providerName="System.Data.SqlClient"/>
</connectionStrings>
.
.
.
<roleManager>
<providers>
<add name="AspNetSqlRoleProvider" connectionStringName="LocalSqlServer" ...
</providers>
</roleManager>
很可能您没有安装 SQL Express,这就是您遇到超时和 SQL 异常的原因。
对于 ASP.NET Identity 不要使用 System.Web.Security.Roles
(它是 ASP.NET Membership 的一部分)但是使用 Microsoft.AspNet.Identity.RoleManager
代替。
关于authentication - 无法连接到数据库以执行身份功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21170525/