【问题标题】:Populating User.Identity in ASP.NET MVC 5在 ASP.NET MVC 5 中填充 User.Identity
【发布时间】:2016-01-05 20:12:47
【问题描述】:

我正在使用 ASP.NET MVC 5 和 SignalR 编写一个简单的聊天应用程序。该应用程序不需要任何复杂的身份验证逻辑。用户只需输入他们的登录名并进入系统(如果数据库中没有这样的用户,则创建它)。

我的意图是使用 Session 来保存登录用户及其信息(来自数据库的 ID 和登录名/用户名),并编写一个全局过滤器来检查用户是否在每个请求上都经过身份验证。不过,我对 SignalR 有一些问题。无法从 SignalR Hub 访问会话,而我需要它来找出发送消息的用户的登录名。

据我所知,可以使用 SignalR 的 Context 处理 User.Identity。但是,就我而言, Uder.Identity 是完全空的。大概是因为我将应用程序创建为“无身份验证”,并且 User.Identity 用于获取用户数据的机制不知道我对会话的操作。

问题是,是否可以优雅地将 User.Identity 集成到我的应用程序中并让它知道 Session?使用单个用户帐户创建 ASP.NET MVC 项目会造成诸如

之类的混乱
public AccountController() :
this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
{

}

这就是我无论如何都不想在我的应用程序中拥有的东西,因为我想尽可能干净地编写它并且不使用任何我不熟悉的解决方案。我也不需要任何外部登录提供程序、cookie 等。

我正在考虑自己实现一些内存存储。但是,我仍然需要在某个时间点清理这家商店。我想在 Session_End 事件被触发时清理它。但是,只有在 Session 中有我不想拥有的数据时才会触发此事件,因为拥有独立的内存存储并依赖 Session 事件来清理它会很尴尬,此外,设置Session 中的一些数据只是为了确保 Session_End 会触发。

【问题讨论】:

    标签: c# asp.net-mvc session signalr


    【解决方案1】:

    这是我想出的解决方案。它仍然不像我希望的那样清晰,它使用 cookie,所以欢迎添加任何内容。

    首先,我必须安装 Microsoft.AspNet.Identity.Owin 包及其所有依赖项。

    然后我按如下方式注册了我的身份验证:

            private void ConfigureAuth(IAppBuilder app)
            {
                app.UseCookieAuthentication(new CookieAuthenticationOptions
                {
                    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                    LoginPath = new PathString("/Account/Login")
                });
            }
    

    然后在 Startup.cs 文件的 Configuration 方法中调用该方法。

    为了使用身份验证,需要一个 IAuthenticationManager 实例。我将它注入我的控制器并使用 Ninject 来解决依赖关系

     kernel.Bind<IAuthenticationManager>().ToMethod(_ => HttpContext.Current.GetOwinContext().Authentication).InRequestScope();
    

    这是需要身份验证时将用户重定向到的 Account 控制器的 Login 方法(感谢 ConfigureAuth 方法中的 LoginPath):

        [HttpPost]
        public ActionResult Login(LoginViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return View(model);
            }
            var user = authenticationService.AuthenticateUser(model.Login);
            IdentitySignIn(user.Id, user.Login);
            return RedirectToAction("Index", "Home");
        }
    

    AuthenticationService 是我自己的类,它与数据库通信并执行登录以创建或返回用户。

    IdentitySignIn 声明如下:

            private void IdentitySignIn(int userId, string userLogin)
            {
                var claims = new List<Claim>();
                claims.Add(new Claim(ClaimTypes.PrimarySid, userId.ToString()));
                claims.Add(new Claim(ClaimTypes.Name, userLogin));
    
                var identity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);
    
                authenticationManager.SignIn(new AuthenticationProperties()
                    {
                        ExpiresUtc = DateTime.UtcNow.AddDays(200),
                        IsPersistent = true
                    }, identity);
            }
    

    此方法创建一个带有适当信息的 cookie。不过,有一件事。当我查看cookie过期日期时,它不是当前日期加上200天,这有点尴尬。

    SignOut 方法很简单:

            public void IdentitySignout()
            {
                authenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
            }
    

    因此,现在可以在 SignalR 集线器中使用 Identity.Name 属性访问 User.Identity。

    要做的事情:通过 User.Identity.Id 之类的方式访问 Id 属性也很好。据我所知,它需要实现自定义主体。 我还在考虑使用 cookie 在客户端存储会话 ID 来实现我自己的某种会话,尽管它肯定会比使用 Identity 花费更多的时间。

    补充: 为了获取用户 ID,可以使用 IdentityExtensions 的扩展方法:

    (在集线器内)

    Context.User.Identity.GetUserId()
    

    为了使其工作,具有用户 id 值的声明应具有类型 ClaimTypes.NameIdentifier。

     var claims = new List<Claim>();
     claims.Add(new Claim(ClaimTypes.NameIdentifier, userId.ToString()));
     claims.Add(new Claim(ClaimTypes.Name, userLogin));
    

    更新 2:

    这里有一些关于这个主题的附加链接,对我有很大帮助。我不包含指向 MS 指南的链接,因为它们很容易找到。

    http://leastprivilege.com/2015/07/21/the-state-of-security-in-asp-net-5-and-mvc-6-claims-authentication/

    http://weblog.west-wind.com/posts/2015/Apr/29/Adding-minimal-OWIN-Identity-Authentication-to-an-Existing-ASPNET-MVC-Application

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-17
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多