2014-09-07 2 views
1

Мне нужно написать пользовательский файл cookie для клиента после входа пользователя. Этот проект использует Asp.Net Identity 2.0 и шаблон Visual Studio MVC 5 по умолчанию, поэтому он больше не прямой как это было в прошлом.Пишите cookie клиенту после входа в систему

Я думал, что место, чтобы сделать это было бы внутри метода ApplicationUser.GenerateUserIdentityAsync(), но HttpContext.Current всегда нуль, когда этот метод выполняется, и я предполагаю, что его из-за его объявлен как асинхронный Task<> и вызывается из отдельного потока.

Я также попытался создать событие в классе 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); 
    } 
} 

ответ

1

Получил эту работу сегодня. Правильное местоположение в ящике, чтобы что-то сделать после того, как пользователь вошел в систему и создал Identity, находится в файле Startup.Auth.cs в делегате CookieAuthenticationProvider.OnResponseSignIn.

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! 
       } 
      } 
     }); 
} 

Я пошел вниз много отверстий кролика обучения о TAP и почему HttpContext может быть нулевым, когда задачи выполняются, но все эти тупики в этом контексте. Я говорю это следующее утверждение, не будучи на 100% уверенным, но я считаю, что большинство асинхронных методов API Asp.Net Identity 2.0 API полностью отделены от конвейера Asp.Net и не имеют доступа ни к чему, кроме того, что передается им в качестве аргументов к промежуточному программному обеспечению OWIN.

aspnet:UseTaskFriendlySynchronizationContext до true не имеет никакого влияния.

+0

Что такое *** SecurityStampValidator ***? и 'OwinContext.GetUserManager '? – Kiquenet

+0

'aspnet: UseTaskFriendlySynchronizationContext' to *** true *** имеет эффект _performance_? – Kiquenet

0

Зачем вам нужен пользовательский cookie?

OWIN cookie зашифрован, а испорченность его содержимым приведет к его недействительности. Я сделал write a blog post о формате файла cookie. И все, что вы делаете с ним, вероятно, сломает трубопровод OWIN.

Если вам нужно добавить дополнительные данные в файл cookie, вы можете добавить претензии на созданный объект идентификации в GenerateUserIdentityAsync и передать эту идентификацию OWIN.
Позже в последующих запросах эти данные будут доступны в ClaimsPrincipal.Current.Claims, а также будут корректно сохранены в файле cookie в соответствии с алгоритмами OWIN.

 Смежные вопросы

  • Нет связанных вопросов^_^