9

Przeglądałem aktualną literaturę, ale staram się dokładnie ćwiczyć, jak sprawić, by nowy system IdentityStore działał z własną bazą danych.Jak używać nowego uwierzytelniania MVC5 z istniejącą bazą danych

Tabela użytkowników mojej bazy danych nazywa się tblMember przykładową klasą poniżej.

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

obecnie użytkownicy zalogować się membership_id który jest unikalny, a potem użyć identyfikatora w całym systemie, który jest kluczem podstawowym. Nie mogę użyć scenariusza nazwy użytkownika do logowania, ponieważ nie jest on wystarczająco unikalny w tym systemie.

Z przykładami, które widziałem wygląda na to, że system jest dla mnie dość elastyczny, ale obecnie nie mogę się nauczyć, jak uzyskać lokalny login, aby użyć mojej tabeli tblmember do uwierzytelnienia za pomocą membership_id, a następnie będę miał dostęp do że użytkownicy tblMember rekord z dowolnego kontrolera za pośrednictwem właściwości User.

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

Odpowiedz

4

Zakładając, że używasz EF, powinieneś być w stanie zrobić coś takiego:

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

Zasadniczo lokalny sklep hasło jest nazywany IUserSecretStore w nowym systemie. Powinieneś być w stanie podłączyć typu jednostki do konstruktora AccountController jak więc zakładając, że wszystko poprawnie wdrożone:

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

Uwaga własność użytkownika będzie zawierał żądania użytkownika, a roszczenie NameIdentifier będzie mapować do IUser.Id właściwość w systemie tożsamości. To nie jest bezpośrednio związane z IUserSecret, który jest tylko nazwą użytkownika/tajnym magazynem. Modele systemów lokalnego hasło jako lokalnego logowania z providerKey = nazwa użytkownika i loginProvider = "local"

Edit: Dodawanie Przykładem niestandardowego użytkownika, jak również

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: Występuje również błąd w implementacji IdentityAuthenticationmanager.GetUserClaims, który jest przesyłany do użytkownika zamiast do IUser, więc niestandardowi użytkownicy, którzy nie rozszerzają się od użytkownika, nie będą działać.

Oto kod, który można użyć do nadpisania:

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

mógłbyś dostarczyć kompletny przykład. Chciałbym użyć mojej własnej klasy użytkownika, która mapuje do mojej tabeli Użytkownicy. Wygląda na to, że nie jestem jedynym, który szuka rozwiązania: http://stackoverflow.com/questions/17399933/how-do-i-conconfigure-the-users-context-table –

+0

Zmieniono moją odpowiedź na niestandardową Użytkownik, najprawdopodobniej zaimplementowałby IUser zamiast rozszerzać Użytkownika, ale reszta kodu powinna być taka sama –

+0

@Hao Kung, obecnie jestem zdezorientowany, jak poprawnie to zaimplementować, doceniam to, że jest jeszcze w wersji beta, ale tam nie ma żadnych szczegółów na temat dostosowywania i łączenia z własną bazą danych/hasłem, czy są jakieś przykłady/zasoby, o których wiecie? – Tim

Powiązane problemy