2013-10-08 56 views
45

Sto osservando le interfacce sulle nuove classi di identità ASP.NET e il database creato utilizzando Entity Framework Code First. Sto usando il Visual Studio 2013 RC.Perché le interfacce di identità ASP.NET utilizzano stringhe per chiavi primarie e esterne?

A prima vista lo schema del database appare ragionevolmente normale:

enter image description here

Ma tutti i tasti sono NVARCHAR (128)

E per qualche ragione folle AspNetUserSecrets.Id è un PK che assomiglia potrebbe indicare più di un record nella tabella AspNetUsers. Significa che più AspNetUsers dovrà condividere la stessa password?

Quando guardo la Guardando le interfacce si è costretti a implementare, queste sono tutte le stringhe ...

public class User : IUser 
{ 
    public string Id { get; set; } 
    public string UserName { get; set; } 
} 

public class UserSecret : IUserSecret 
{ 
    public string UserName { get; set; } 
    public string Secret { get; set; } 
} 

public class UserRole : IUserRole 
{ 
    public string UserId { get; set; } 
    public string RoleId { get; set; } 
} 

public class UserClaim : IUserClaim 
{ 
    public string UserId { get; set; } 
    public string ClaimType { get; set; } 
    public string ClaimValue { get; set; } 
} 

public class UserManagement : IUserManagement 
{ 
    public string UserId { get; set; } 
    public bool DisableSignIn { get; set; } 
    public DateTime LastSignInTimeUtc { get; set; } 
} 

public class Tokens : IToken 
{ 
    public string Id { get; set; } 
    public string Value { get; set; } 
    public DateTime ValidUntilUtc { get; set; } 
} 

public class UserLogin : IUserLogin 
{ 
    public string UserId { get; set; } 
    public string LoginProvider { get; set; } 
    public string ProviderKey { get; set; } 
} 

public class Role : IRole 
{ 
    public string Id { get; set; } 
    public string Name { get; set; } 
} 

Così sto venendo a patti con il fatto che io possa avere per implementare questo usando le stringhe per le relazioni PK e FK.

Ma mi piacerebbe davvero sapere PERCHE 'è costruito in questo modo ...?

EDIT: Il tempo è passato e ora ci sono articoli su come estendere l'identità asp.net da usare int (o GUID) campi:

http://www.asp.net/identity/overview/extensibility/change-primary-key-for-users-in-aspnet-identity

+0

Si sta utilizzando una versione beta. La versione finale è diversa dalla mia comprensione. Ho sentito che hanno rimosso completamente la tabella AspNetUserSecrets. –

+0

Beh, questo risolverà uno dei problemi :) Ma continuo a non capire perché tutte le chiavi siano NVARCHER (128) ... –

risposta

31

L'intento è stato quello di consentire sia tipi di ID arbitrari (ad esempio int, guid, string), ma anche evitare di avere problemi di serializzazione/trasmissione per la proprietà id.

Quindi è possibile definire le chiavi come più vi piace e basta implementare il metodo di interfaccia

public class MyUser : IUser { 
    public int Id { get; set; } 
    string IUser.Id { get { return Id.ToString(); } } 
} 
+0

Scusa perché la risposta è stata fornita da una persona all'interno avrei dovuto contrassegnarla come corretto molto tempo fa. –

+0

Perchè se questo è l'unico codice necessario per usare un id come int, abbiamo 'InEnumerable ' come questo: http://typecastexception.com/post/2014/07/13/ASPNET-Identity-20-Extending-Identity -Models-and-Using-Integer-Keys-Invece-of-Strings.aspx dappertutto? –

+1

Questo è tutto ciò che è necessario dal punto di vista di Identity, ci sarà un gran numero di modifiche al codice dell'app corrispondenti. Questo è stato abbastanza travolgente in generale, e abbiamo già provato a semplificare questo gruppo in Identity V3. –

16

Aggiungendo a ciò Hao ha detto:

  1. Il runtime Identity preferisce stringhe per l'ID utente perché don "Voglio essere nel business della ricerca della corretta serializzazione degli user ID (usiamo stringhe anche per claim per lo stesso motivo), ad es. tutte (o la maggior parte) delle interfacce Identity si riferiscono all'ID utente sotto forma di stringa.
  2. Le persone che personalizzano il livello di persistenza, ad es. i tipi di entità, possono scegliere qualsiasi tipo di chiave per le chiavi, ma poi possiedono la fornitura di una rappresentazione in formato stringa delle chiavi.
  3. Per impostazione predefinita, utilizziamo la rappresentazione di stringa di GUID per ogni nuovo utente, ma ciò è solo perché fornisce un modo molto semplice per noi di generare automaticamente ID univoci.
+1

È ora di C# implementare diverse firme di metodo basate anche sul tipo restituito. Poiché si tratta di una limitazione, Microsoft non può creare un pacchetto Identity.EntityFramework.Int, uno GuiD e tutte le opzioni? –

+1

@Rick Perché nvarchar (128) invece di uniqueidentifier? –

2

Con ASP.NET Core, si dispone di un modo molto semplice per specificare il tipo di dati desiderato per i modelli di Identity.

Primo passo, le classi di sostituzione di identità da < string> a dati < tipo che si desidera>:

public class ApplicationUser : IdentityUser<Guid> 
{ 
} 

public class ApplicationRole : IdentityRole<Guid> 
{ 
} 

dichiarare il vostro contesto del database, utilizzando le classi e il tipo di dati che si desidera:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, Guid> 
    { 
     public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) 
      : base(options) 
     { 
     } 

     protected override void OnModelCreating(ModelBuilder builder) 
     { 
      base.OnModelCreating(builder); 
      // Customize the ASP.NET Identity model and override the defaults if needed. 
      // For example, you can rename the ASP.NET Identity table names and more. 
      // Add your customizations after calling base.OnModelCreating(builder); 
     } 
    } 

E nella classe di avvio, dichiarare il servizio di identità utilizzando i modelli e dichiarare il tipo di dati desiderato per il prim Tasti ary:

services.AddIdentity<ApplicationUser, ApplicationRole>() 
      .AddEntityFrameworkStores<ApplicationDbContext, Guid>() 
      .AddDefaultTokenProviders(); 

Nelle tabelle di identità ASP.NET, le chiavi primarie saranno ancora in NVARCHAR ma nell'applicazione E 'sarà il tipo di dati che si desidera. È possibile controllare questo in un controller:

[HttpGet] 
    public async Task<IActionResult> Test() 
    { 
     ApplicationUser user = await _userManager.GetUserAsync(HttpContext.User); 
     Guid userId = user.Id; // No cast from string, it's a Guid data type 
     throw new NotImplementedException(); 
    } 
+1

C'è un articolo nella documentazione ufficiale da questa risposta: https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity-primary-key-configuration – AdrienTorris

+0

Cosa succede se non desidero definire i ruoli, stiamo gestendo i ruoli da ACL. – Khalil

Problemi correlati