2014-10-26 24 views
7

Tôi gặp sự cố khi nhận dạng ASP Identity để làm mới Danh tính được lưu trữ trong cookie theo yêu cầu.ASP Identity 2.0: Regenerate Identity

Trong Startup.Auth.cs tập tin cookie được thiết lập để tái sinh như sau:

app.UseCookieAuthentication(new CookieAuthenticationOptions 
      { 
       AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
       LoginPath = new PathString("/Account/Login"), 
       Provider = new CookieAuthenticationProvider 
       { 
        OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<QuizSparkUserManager, QuizSparkUser, int>(
        validateInterval: TimeSpan.FromMinutes(30), 
        regenerateIdentityCallback: ((manager, user) => manager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie)), 
        getUserIdCallback: ((claimsIdentity) => int.Parse(claimsIdentity.GetUserId()))) 
       } 
      }); 

Tuy nhiên tôi không thể làm việc ra làm thế nào để làm mới nội dung trên User.Identity trong mã, tức là buộc phải refresh lại cookie sắc khi tôi cần nó để làm mới.

Tôi muốn có thể sử dụng tính năng gọi lại tái tạo nhận dạng theo chương trình, điều này có khả thi không?

Vấn đề của tôi cũng tương tự như thế này: How to invalidate .AspNet.ApplicationCookie after Adding user to Role using Asp.Net Identity 2?

Tuy nhiên tôi muốn làm mới chứ không phải là vô hiệu hóa cookie.

Sửa


Sau khi xem xét các câu hỏi liên quan Tôi đã cố gắng như sau (mà không xử lý lỗi đầy đủ):

IOwinContext context = Request.GetOwinContext(); 
QuizSparkSignInManager manager = context.Get<QuizSparkSignInManager>(); 
ClaimsIdentity newIdentity = manager.CreateUserIdentity(manager.UserManager.FindById(User.Identity.GetUserId<int>())); 

AuthenticateResult authenticationContext = 
        await context.Authentication.AuthenticateAsync(DefaultAuthenticationTypes.ApplicationCookie); 

if (authenticationContext != null) 
{ 
    context.Authentication.AuthenticationResponseGrant = new AuthenticationResponseGrant(
         newIdentity, authenticationContext.Properties); 
} 

bool first2 = User.IsInRole("Turtle"); 

Edit2: Tuy nhiên người dùng vẫn không xuất hiện để làm mới. Trên trang tải lại họ dường như làm mới, tôi phải trong suy nghĩ này là bởi vì cookie User.Identity là một phần của yêu cầu và không thể được thay đổi trong mã?

+0

Bạn đang cố gắng làm gì bằng cách làm mới cookie? – trailmax

+0

Khi bạn giải quyết trong câu trả lời của mình, tôi đang cố làm mới vai trò người dùng khi người dùng được thêm vào vai trò. – Underscore

+0

Đây là câu hỏi rất giống: http://stackoverflow.com/a/19354940/809357 – trailmax

Trả lời

8

Nếu bạn đang cố gắng thêm vai trò mới cho người dùng đã đăng nhập, bạn cần đăng xuất người dùng. Sau đó, tạo danh tính mới với vai trò mới và đăng nhập người dùng bằng danh tính mới. Đó là cách duy nhất để cập nhật cookie.

Nơi tốt nhất để kiểm tra xem thuộc tính người dùng đã thay đổi có gọi lại bạn đã sử dụng: CookieAuthenticationProvider.OnValidateIdentity hay không. Một cái gì đó như thế này.

app.UseCookieAuthentication(new CookieAuthenticationOptions 
{ 
    // other stuff 
    Provider = new CookieAuthenticationProvider 
    { 
     // this function is executed every http request and executed very early in the pipeline 
     // and here you have access to cookie properties and other low-level stuff. 
     // makes sense to have the invalidation here 
     OnValidateIdentity = async context => 
     { 
      // invalidate user cookie if user's security stamp have changed 
      var invalidateBySecirityStamp = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
        validateInterval: TimeSpan.FromMinutes(30), 
        regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager)); 
      await invalidateBySecirityStamp.Invoke(context); 

      if (context.Identity == null || !context.Identity.IsAuthenticated) 
      { 
       return; 
      } 
      if(/*Need to update cookie*/) 
      { 
       // get user manager. It must be registered with OWIN 
       var userManager = context.OwinContext.GetUserManager<UserManager>(); 
       var username = context.Identity.Name; 

       // get new user identity with updated properties 
       var updatedUser = await userManager.FindByNameAsync(username); 

       // updated identity from the new data in the user object 
       var newIdentity = updatedUser.GenerateUserIdentityAsync(manager); 

       // kill old cookie 
       context.OwinContext.Authentication.SignOut(context.Options.AuthenticationType); 

       // sign in again 
       var authenticationProperties = new AuthenticationProperties() { IsPersistent = context.Properties.IsPersistent }; 
       context.OwinContext.Authentication.SignIn(authenticationProperties, newIdentity); 
      } 
     } 
    } 
}); 

Tuyên bố từ chối - không bao giờ thử nghiệm, thậm chí không cố biên dịch.

Cũng có thể see my other answer để tham khảo - khá nhiều đoạn mã giống nhau, nhưng mục tiêu khác nhau.

UPD: Về một phần khác của câu hỏi - làm thế nào để phát hiện một sự thay đổi vai trò:
tôi có thể nghĩ ra một cách - có một GUID trên một hồ sơ người dùng. Tương tự như SecurityStamp, nhưng không được sử dụng bởi khung công tác. Gọi nó là MySecurityStamp. Khi thêm giá trị đăng nhập MySecurityStamp vào cookie làm xác nhận quyền sở hữu. Trên mọi yêu cầu, hãy so sánh giá trị của MySecurityStamp trong cookie với giá trị trong cơ sở dữ liệu. Nếu các giá trị khác nhau - thời gian để tạo lại danh tính. Và trên mỗi vai trò mới được thêm/xóa sửa đổi MySecurityStamp cho người dùng trong cơ sở dữ liệu. Điều này sẽ bao gồm tất cả các phiên trong tất cả các trình duyệt.

+0

Hiện tại, tôi chỉ tạo lại danh tính và đăng nhập, bạn có biết rằng dấu hiệu bổ sung cần thiết để tiêu diệt cookie hay nó sẽ bị vô hiệu hóa bởi lệnh gọi '' 'Authentication.AuthenticationResponseGrant'''? – Underscore

+0

Tại sao bạn sử dụng 'Authentication.AuthenticationResponseGrant'?Tôi không nghĩ rằng điều này nên được tiêu thụ bởi bất cứ điều gì khác hơn OWIN chính nó. Và để giết cookie bạn cần sử dụng 'Authentication.AuthenticationResponseRevoke' (hoặc một cái gì đó như thế này, không chắc chắn về việc đặt tên). Dù sao, chỉ cần sử dụng 'SignOut' - hiện các phản hồi và cấp cho bạn trong nền. – trailmax

+0

Từ các tài liệu, có vẻ như '' 'AuthenticationResponseGrant''' và' '' AuthenticationResponseRevoke''' chỉ là các trình truy cập được nhập mạnh cho '' 'SignIn''' và' '' SignOut''' nhưng tôi lấy điểm và cảm ơn vì đã dành thời gian để thực hiện điều này. – Underscore

Các vấn đề liên quan