Asp.net mvc 5 登录后向客户端写入cookie

Asp.net mvc 5 登录后向客户端写入cookie,asp.net-mvc-5,asp.net-identity-2,Asp.net Mvc 5,Asp.net Identity 2,我需要在用户登录后向客户端写入自定义cookie。此项目使用Asp.NETIdentity 2.0和默认的VisualStudioMVC5模板,因此它不再像过去那样简单 我认为这样做的地方应该在ApplicationUser.GenerateUserIdentityAsync()方法中,但是HttpContext.Current在执行此方法时总是空的,我假设它是空的,因为它声明为异步任务,并且从单独的线程调用 我还尝试在ApplicationUser类中创建一个事件,但这也不起作用,因为它也是从

我需要在用户登录后向客户端写入自定义cookie。此项目使用Asp.NETIdentity 2.0和默认的VisualStudioMVC5模板,因此它不再像过去那样简单

我认为这样做的地方应该在
ApplicationUser.GenerateUserIdentityAsync()
方法中,但是
HttpContext.Current
在执行此方法时总是空的,我假设它是空的,因为它声明为异步
任务,并且从单独的线程调用

我还尝试在
ApplicationUser
类中创建一个事件,但这也不起作用,因为它也是从单独的线程调用的。我可以将此方法重新编写为同步,但我想知道使用Microsoft提供的开箱即用模板执行此操作的正确方法是什么

public class ApplicationUser : IdentityUser<int, CustomUserLogin, CustomUserRole, CustomUserClaim>
{
    public ApplicationUser()
    {
        LastLogin = String.Empty;
        HasLoggedInBefore = false;

        UserCreated += ApplicationUser_UserCreated;
    }

    void ApplicationUser_UserCreated(object sender, ApplicationUser user)
    {
        // write our custom cookie
        user.WriteDetailsCookie();
    }

    public event EventHandler<ApplicationUser> UserCreated;
    protected virtual void OnUserCreated(ApplicationUser user)
    {
        EventHandler<ApplicationUser> handler = UserCreated;
        if (handler != null)
        {
            handler(this, user);
        }
    }

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser, int> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        OnUserCreated(this); // fire our event
        return userIdentity;
    }

    public void WriteDetailsCookie()
    {
        var lastLoginCookie = new HttpCookie("UserDetails");
        lastLoginCookie.Values.Add("userName", UserName);
        lastLoginCookie.Values.Add("lastLogin", DateTime.UtcNow.ToString("G"));
        lastLoginCookie.Expires = DateTime.Now.AddDays(90d);
        HttpContext.Current.Response.Cookies.Add(lastLoginCookie);
    }
}
公共类应用程序用户:IdentityUser
{
公共应用程序用户()
{
LastLogin=String.Empty;
HasLoggedInBefore=假;
UserCreated+=应用程序用户\用户创建;
}
无效ApplicationUser\u UserCreated(对象发送方,ApplicationUser用户)
{
//编写自定义cookie
user.WriteDetailsCookie();
}
创建公共事件事件处理程序;
已创建受保护的虚拟用户(ApplicationUser用户)
{
EventHandler=UserCreated;
if(处理程序!=null)
{
处理程序(此,用户);
}
}
公共异步任务GenerateUserIdentityAsync(用户管理器)
{
//注意authenticationType必须与CookieAuthenticationOptions.authenticationType中定义的类型匹配
var userIdentity=wait manager.CreateIdentityAsync(这是DefaultAuthenticationTypes.ApplicationOkie);
OnUserCreated(此);//启动我们的活动
返回用户身份;
}
公共无效写入的tailscookie()
{
var lastLoginCookie=新的HttpCookie(“用户详细信息”);
lastLoginCookie.Values.Add(“用户名”,userName);
添加(“lastLogin”,DateTime.UtcNow.ToString(“G”);
lastLoginCookie.Expires=DateTime.Now.AddDays(90d);
HttpContext.Current.Response.Cookies.Add(lastLoginCookie);
}
}

今天就开始工作了。用户登录并创建标识后,正确的开箱即用位置位于
CookieAuthenticationProvider.OnResponseSignIn
委托中的
Startup.Auth.cs
文件中

    public void ConfigureAuth(IAppBuilder app)
    {
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
            Provider = new CookieAuthenticationProvider
            {
                OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser, int>(
                    validateInterval: TimeSpan.FromMinutes(30),
                    regenerateIdentityCallback: (manager, user) => user.GenerateUserIdentityAsync(manager),
                    getUserIdCallback: (id) => (Int32.Parse(id.GetUserId()))),
                OnResponseSignIn = cookieSignInCtx =>
                {
                    // do your post identity creation stuff here
                    var userManager = cookieSignInCtx.OwinContext.GetUserManager<ApplicationUserManager>();
                    var user = userManager.FindById(cookieSignInCtx.Identity.GetUserId<int>());
                    if (user != null)
                        user.WriteDetailsCookie(HttpContext.Current); // HttpContext.Current is not null, yeah!
                }
            }
        });
}
public void ConfigureAuth(IAppBuilder应用程序)
{
app.UseCookieAuthentication(新的CookieAuthenticationOptions
{
AuthenticationType=DefaultAuthenticationTypes.ApplicationOkie,
LoginPath=新路径字符串(“/Account/Login”),
Provider=新CookieAuthenticationProvider
{
OnValidateIdentity=SecurityStampValidator.OnValidateIdentity,以及为什么在执行任务时HttpContext可能为null,但这些都是此上下文中的死胡同。我说下一句话时没有100%的把握,但我相信大多数Asp.Net Identity 2.0 API异步方法都完全脱离了Asp.Net管道,没有由于OWIN中间件,除了作为参数传递给它们的内容之外,还可以访问任何内容


设置为
true
没有影响。

为什么需要自定义cookie

OWIN cookie是加密的,弄乱它的内容只会使它失效。我对cookie格式做了修改。你对它做的任何事情都可能会破坏OWIN管道

如果需要在cookie中添加额外数据,可以在
GenerateUserIdentityAsync
中将声明添加到创建的标识对象上,并将该标识传递给OWIN。

在以后的请求中,这些数据将在
ClaimsPrincipal.Current.Claims中可用,并且它将根据OWIN算法正确地存储在cookie中。

什么是SecurityStampValidator?和
OwinContext.GetUserManager
aspnet:UseTaskFriendlySynchronizationContext
对true具有性能影响计算机断层扫描?