MVC 5和ASP.NET Identity的实现混淆

12

我正在创建一个新的 Web 应用程序,使用MVC 5Entity Framework 数据库优先方法编写。我还想使用ASP.Net Identity管理成员资格、认证、授权等功能。

我已经在网上阅读了关于 ASP.Net Identity 的很多信息以及它的工作原理,但是我仍然在学习这个主题。

当我在 Visual Studio 2013 中创建我的 MVC 5 应用程序并查看Account Controller时,我的第一反应是我不喜欢我所看到的,即引用了名为“ApplicationDbContext”的DbContext。我不喜欢这个的原因是因为我想把我的 DbContext 保留在适当的项目中,也就是我的模型层,在那里它遵循关注点分离逻辑。

此外,默认情况下,MVC 5 项目会使用 Entity Framework Code First 来创建数据库和表,以存储用户、角色等信息。

由于我必须使用现有的数据库和现有的用户表,这种方法不适合我的需求。

尽管如此,我仍然想在我的应用程序中使用最新的 ASP.Net Identity,因为它看起来有很多好处。因此,我发现了这篇文章,剥离了很多 Entity Framework 代码,但仍然将 OWIN 动力认证引入了 ASP.NET MVC 中。

http://www.khalidabuhakmeh.com/asp-net-mvc-5-authentication-breakdown-part-deux

使用上述教程,这是我的Account Controller中的HttpPost 登录方法:

    [HttpPost]
    [AllowAnonymous]
    public ActionResult Login(LoginViewModel model, string returnUrl)
    {
        if (ModelState.IsValid)
        {
            //Calling my own custom Account Service which validates users login details
            var user = _AccountService.VerifyPassword(model.UserName, model.Password, false);
            if (user)
            {
                var identity = new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, model.UserName), }, DefaultAuthenticationTypes.ApplicationCookie, ClaimTypes.Name, ClaimTypes.Role);

                //ToDo: Manually adding Role, but will pull from db later
                identity.AddClaim(new Claim(ClaimTypes.Role, "guest"));

                AuthenticationManager.SignIn(new AuthenticationProperties
                {
                    IsPersistent = model.RememberMe
                }, identity);

                return RedirectToAction("Index", "MyDashboard");
            }
            else
            {
                ModelState.AddModelError("", "Invalid username or password.");
            }
        }

        return View(model);
    }
在我之前的MVC应用程序中,我通常会自己编写自定义成员资格。当用户登录站点并通过身份验证时,我会将任何附加用户详细信息(例如userID,DOB等)存储在FormsAuthenticationTicket的UserData字符串中。
由于上面的代码未使用FormsAuthentication,而是使用OWIN CookieAuthentication,因此我不确定如何存储此附加用户数据。
因此,我有几个关于我遇到问题的问题。
1. 我该如何存储userID或任何其他附加的用户数据(如DOB等),就像以前在FormsAuthentication中所做的那样?这是否通过向身份添加声明来完成? 2. 考虑到我正在使用现有数据库的Entity Framework Database First,上述使用ASP.Net Identity/ OWIN的方法是否正确? 3. 我应该使用Account Controller中使用的开箱即用的代码,例如UserManager,ApplicationUser,ApplicationDbContext等,并将其连接起来以与我的现有数据库一起使用吗?
如果我的问题很困惑,我很抱歉,我想我只是有点不确定我应该在尝试在我的最新项目中使用ASP.Net Identity时采取什么方法。
非常感谢您的任何反馈。

嗨@tgriffiths,我和你当时处于同样的情况...你能告诉我你正在使用什么方法来帮助我吗? - Lakshay Dulani
2个回答

4

1) 新的Katana Cookie中间件支持声明。这使得它比表单身份验证Cookie更好;声明模型可以存储任何键/值对,并且这些可以存储在身份验证Cookie中。有关详细信息,请参见此文章:

http://brockallen.com/2013/10/24/a-primer-on-owin-cookie-authentication-middleware-for-the-asp-net-developer/

2和3)就身份数据的存储而言,如果您需要使用现有表格进行操作,则可能无法使用Microsoft提供的EF提供的类。相反,您将自己实现IUserStore和所有其他存储接口所需的应用程序。我不确定改变已经使用的用户数据存储是否值得。

请记住,OWIN / Katana部分与身份存储是分开的。


谢谢,布洛克。你关于OWIN身份验证的文章非常有帮助。为了将用户ID作为声明存储,我可以像这样执行claims.Add(new Claim(ClaimTypes.UserID, "2"))吗? - tcode
我能请你看一下这个问题吗?我试图添加到我的身份中的声明似乎没有正确添加。谢谢。https://dev59.com/mmEi5IYBdhLWcg3wUK2C#21405315?noredirect=1#comment32305209_21405315 - tcode
@tgriffiths 是的,在发出 cookie 时添加任何声明。 - Brock Allen
谢谢Brock。你能看一下并可能回答这个问题吗?https://dev59.com/ynnZa4cB1Zd3GeqPuMNu?rq=1 这正是我所遇到的问题。谢谢。 - tcode
你好,现有控制器中的Authorize属性是否会继续生效? - Ernesto
授权只是针对用户的声明进行检查。因此,角色检查会查找角色声明,例如。 - Brock Allen

2

以下是解决方案

为了加快进度,您可以将示例应用程序添加到您的项目中,并通过修改示例应用程序开始。示例应用程序包括确认电子邮件、密码恢复、角色管理员和用户角色管理等功能。NuGet软件包位于:NuGet package

Install-Package Microsoft.AspNet.Identity.Samples -Pre 

这里可以查看有关示例应用程序的完整详细信息:ASP.NET Identity 2.0:自定义用户和角色

使用以下属性控制对控制器或操作的访问

[Authorize] //Anyone with authorization
[Authorize(Roles="Administrator")] //Admin role only

检查用户角色:

HttpContext.User.IsInRole("Administrator")
UserManager.IsInRole(userID, "Administrator")

通过以下方式获取个人资料数据

// Create manager
 var manager = new UserManager<ApplicationUser>(
    new UserStore<ApplicationUser>(new ApplicationDbContext()))

// Find user
var user = manager.FindById(User.Identity.GetUserId());
var profileProperty_1 = user.profileProperty_1 

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