C# 在ASP.NET MVC 5中填充User.Identity

C# 在ASP.NET MVC 5中填充User.Identity,c#,asp.net-mvc,session,signalr,C#,Asp.net Mvc,Session,Signalr,我正在使用ASP.NETMVC5和SignalR编写一个简单的聊天应用程序。应用程序不需要任何复杂的身份验证逻辑。用户只需输入他们的登录名并进入系统(如果数据库中以前没有这样的用户,则创建数据库) 我的意图是使用会话来保存登录用户及其信息(来自数据库的id和登录名/用户名),并编写一个全局过滤器来检查用户是否在每个请求上都经过身份验证。不过我和信号员有些问题。无法从SignalR Hub访问会话,而我需要它来查找发送消息的用户的登录名 正如我所发现的,使用signer的上下文处理User.Ide

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

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

正如我所发现的,使用signer的上下文处理User.Identity是可能的。然而,在我的例子中,Uder.Identity是完全空的。大概是因为我创建的应用程序为“无身份验证”,而User.Identity用于获取用户数据的机制不知道我对会话的操作

问题是,是否有可能将User.Identity优雅地集成到我的应用程序中,并让它知道会话?使用单个用户帐户创建ASP.NETMVC项目会造成混乱,例如

public AccountController() :
this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
{

}
public AccountController():
这是(新的UserManager(新的UserStore(新的ApplicationDbContext()))
{
}
这是我无论如何都不想在我的应用程序中使用的,因为我想写得尽可能干净,不使用我不熟悉的任何解决方案。我也不需要任何外部登录提供商、cookies等


我在考虑自己实现一些内存存储。然而,我仍然需要在某个时候清理这家商店。我想在启动会话结束事件时清理它。但是,只有在会话中有我不想拥有的数据时,才会触发此事件,因为使用独立内存存储并依靠会话事件来清理它会非常困难,而且,在会话中设置一些数据只是为了确保会话结束将触发。

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

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

然后我注册了我的授权,如下所示:

        private void ConfigureAuth(IAppBuilder app)
        {
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Account/Login")
            });
        }
        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);
        }
然后在Startup.cs文件的配置方法中调用此方法

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

 kernel.Bind<IAuthenticationManager>().ToMethod(_ => HttpContext.Current.GetOwinContext().Authentication).InRequestScope();
AuthenticationService是我自己的类,它与数据库通信并执行登录以创建或返回用户

IdentitySignIn声明如下:

        private void ConfigureAuth(IAppBuilder app)
        {
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Account/Login")
            });
        }
        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);
        }
因此,User.Identity现在可以通过Identity.Name属性在signarhub中访问

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

添加: 为了获取用户id,可以使用IdentityExtensions的扩展方法:

(中心内)

为了使其工作,值为user's id的声明应具有类型ClaimTypes.nameignifier

 var claims = new List<Claim>();
 claims.Add(new Claim(ClaimTypes.NameIdentifier, userId.ToString()));
 claims.Add(new Claim(ClaimTypes.Name, userLogin));
var索赔=新列表();
添加(新声明(ClaimTypes.NameIdentifier,userId.ToString());
添加(新索赔(ClaimTypes.Name,userLogin));
更新2:

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

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