9

Tôi đã xem qua tài liệu hiện tại nhưng tôi đang cố gắng tập luyện chính xác cách làm cho hệ thống IdentityStore mới hoạt động với cơ sở dữ liệu của riêng bạn.Cách sử dụng xác thực MVC5 mới với cơ sở dữ liệu hiện có

Bảng người dùng của cơ sở dữ liệu của tôi được gọi là tblMember một lớp ví dụ bên dưới.

public partial class tblMember 
{ 
    public int id { get; set; } 
    public string membership_id { get; set; } 
    public string password { get; set; } 
    ....other fields 
} 

đăng nhập người dùng hiện tại với membership_id là duy nhất và sau đó tôi sử dụng id trong toàn bộ hệ thống là khóa chính. Tôi không thể sử dụng kịch bản tên người dùng để đăng nhập vì nó không đủ độc đáo trên hệ thống này.

Với các ví dụ tôi đã thấy có vẻ như hệ thống được thiết kế khá dễ uốn, nhưng hiện tại tôi không thể tập luyện cách đăng nhập cục bộ để sử dụng bảng tblmember để xác thực bằng cách sử dụng membership_id và sau đó tôi sẽ truy cập người dùng tblHãy ghi lại lịch sử từ bất kỳ bộ điều khiển nào thông qua thuộc tính Người dùng.

http://blogs.msdn.com/b/webdev/archive/2013/07/03/understanding-owin-forms-authentication-in-mvc-5.aspx

Trả lời

4

Giả sử bạn đang sử dụng EF, bạn sẽ có thể làm điều gì đó như thế này:

public partial class tblMember : IUserSecret 
{ 
    public int id { get; set; } 
    public string membership_id { get; set; } 
    public string password { get; set; } 
    ....other fields 

    /// <summary> 
    /// Username 
    /// </summary> 
    string UserName { get { return membership_id; set { membership_id = value; } 

    /// <summary> 
    /// Opaque string to validate the user, i.e. password 
    /// </summary> 
    string Secret { get { return password; } set { password = value; } } 
} 

Về cơ bản các cửa hàng mật khẩu địa phương được gọi là IUserSecretStore trong hệ thống mới. Bạn sẽ có thể cắm vào loại thực thể của bạn vào các nhà xây dựng AccountController như vậy giả sử bạn thực hiện tất cả mọi thứ một cách chính xác:

public AccountController() 
    { 
     var db = new IdentityDbContext<User, UserClaim, tblMember, UserLogin, Role, UserRole>(); 
     StoreManager = new IdentityStoreManager(new IdentityStoreContext(db)); 
    } 

Note sở hữu tài khoản sẽ chứa tuyên bố của người dùng, và tuyên bố NameIdentifier sẽ vạch cho IUser.Id thuộc tính trong hệ thống Identity. Đó không phải là trực tiếp gắn liền với IUserSecret mà chỉ là một tên người dùng/cửa hàng bí mật. Các mô hình hệ thống mật khẩu địa phương như một tên đăng nhập cục bộ với providerKey = tên người dùng, và loginProvider = "Địa phương"

Edit: Thêm một ví dụ về Tuỳ chỉnh tài khoản cũng

public class CustomUser : User { 
     public string CustomProperty { get; set; } 
    } 

    public class CustomUserContext : IdentityStoreContext { 
     public CustomUserContext(DbContext db) : base(db) { 
      Users = new UserStore<CustomUser>(db); 
     } 
    } 

    [TestMethod] 
    public async Task IdentityStoreManagerWithCustomUserTest() { 
     var db = new IdentityDbContext<CustomUser, UserClaim, UserSecret, UserLogin, Role, UserRole>(); 
     var manager = new IdentityStoreManager(new CustomUserContext(db)); 
     var user = new CustomUser() { UserName = "Custom", CustomProperty = "Foo" }; 
     string pwd = "password"; 
     UnitTestHelper.IsSuccess(await manager.CreateLocalUserAsync(user, pwd)); 
     Assert.IsTrue(await manager.ValidateLocalLoginAsync(user.UserName, pwd)); 
     CustomUser fetch = await manager.Context.Users.FindAsync(user.Id) as CustomUser; 
     Assert.IsNotNull(fetch); 
     Assert.AreEqual("Custom", fetch.UserName); 
     Assert.AreEqual("Foo", fetch.CustomProperty); 
    } 

EDIT # 2: Ngoài ra còn có một lỗi trong việc thực hiện IdentityAuthenticationmanager.GetUserClaims được đúc cho người dùng thay vì IUser, do đó, người dùng tùy chỉnh không mở rộng từ người dùng sẽ không hoạt động.

Dưới đây là đoạn code mà bạn có thể sử dụng để ghi đè lên:

internal const string IdentityProviderClaimType = "http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider"; 
    internal const string DefaultIdentityProviderClaimValue = "ASP.NET Identity"; 

/// <summary> 
/// Return the claims for a user, which will contain the UserIdClaimType, UserNameClaimType, a claim representing each Role 
/// and any claims specified in the UserClaims 
/// </summary> 
public override async Task<IList<Claim>> GetUserIdentityClaims(string userId, IEnumerable<Claim> claims) { 
    List<Claim> newClaims = new List<Claim>(); 
    User user = await StoreManager.Context.Users.Find(userId) as IUser; 
    if (user != null) { 
     bool foundIdentityProviderClaim = false; 
     if (claims != null) { 
      // Strip out any existing name/nameid claims that may have already been set by external identities 
      foreach (var c in claims) { 
       if (!foundIdentityProviderClaim && c.Type == IdentityProviderClaimType) { 
        foundIdentityProviderClaim = true; 
       } 
       if (c.Type != ClaimTypes.Name && 
        c.Type != ClaimTypes.NameIdentifier) { 
        newClaims.Add(c); 
       } 
      } 
     } 
     newClaims.Add(new Claim(UserIdClaimType, userId, ClaimValueTypes.String, ClaimsIssuer)); 
     newClaims.Add(new Claim(UserNameClaimType, user.UserName, ClaimValueTypes.String, ClaimsIssuer)); 
     if (!foundIdentityProviderClaim) { 
      newClaims.Add(new Claim(IdentityProviderClaimType, DefaultIdentityProviderClaimValue, ClaimValueTypes.String, ClaimsIssuer)); 
     } 
     var roles = await StoreManager.Context.Roles.GetRolesForUser(userId); 
     foreach (string role in roles) { 
      newClaims.Add(new Claim(RoleClaimType, role, ClaimValueTypes.String, ClaimsIssuer)); 
     } 
     IEnumerable<IUserClaim> userClaims = await StoreManager.Context.UserClaims.GetUserClaims(userId); 
     foreach (IUserClaim uc in userClaims) { 
      newClaims.Add(new Claim(uc.ClaimType, uc.ClaimValue, ClaimValueTypes.String, ClaimsIssuer)); 
     } 
    } 
    return newClaims; 
} 
+0

Ông có thể vui lòng cung cấp một ví dụ hoàn chỉnh. Tôi muốn sử dụng lớp người dùng của riêng tôi để ánh xạ tới bảng Người dùng của tôi. Có vẻ như tôi không phải là người duy nhất tìm kiếm giải pháp: http://stackoverflow.com/questions/17399933/how-do-i-configure-the-users-context-table –

+0

Đã chỉnh sửa câu trả lời của tôi để chứa một tùy chỉnh Người dùng, bạn có thể sẽ triển khai IUser thay vì mở rộng User, nhưng phần còn lại của mã phải giống như –

+0

@Hao Kung, tôi hiện đang bối rối về cách thực hiện điều này một cách chính xác, tôi đánh giá cao điều này vẫn còn trong bản beta nhưng xuất hiện không có chi tiết thực sự về tùy chỉnh và liên kết đến kho lưu trữ cơ sở dữ liệu/mật khẩu của riêng bạn, có thêm bất kỳ ví dụ/tài nguyên nào mà bạn biết không? – Tim