Buona architettura per le informazioni dell'utente su database separati?

5

Devo scrivere un'API per connettermi a un database SQL esistente. L'API verrà scritta in ASP.Net MVC3.

Il leggero problema è che con gli utenti esistenti del sistema, possono avere un nome utente su più database.

Ogni azienda che utilizza il prodotto ottiene una nuova istanza del database, ma nel corso degli anni (il sistema funziona da 10 anni) ci sono alcuni utenti (centinaia) che hanno più nomi utente su più "società" ( le cose sono ovviamente frammentate e talvolta una singola azienda ha 5 "progetti" che hanno ciascuno il proprio database).
Per farla breve, devo essere in grado di avere un unico accesso utente unificato che consentirà agli utenti esistenti di accedere alle loro informazioni attraverso tutti i loro progetti.

L'unica cosa che posso pensare è archiviare un mucchio di stringhe di connessione, ma mi sembra una pessima idea.

Avrò un nuovo Database che conterrà le informazioni "utente unificato" ... qualcuno può suggerire un'architettura di sistema solida in grado di gestire un setup come questo?

    
posta James P. Wright 20.05.2012 - 03:51
fonte

2 risposte

3

Unificazione dei dati

Poiché l'autenticazione era indipendente tra i cinque progetti, è possibile che si verifichino diverse incongruenze:

  • Identificatori diversi. Ad esempio, se gli identificativi dell'utente sono indirizzi e-mail, la stessa persona può registrarsi con [email protected] per un progetto, [email protected] per un altro e [email protected] per un terzo. È praticamente impossibile risolvere questo problema: potresti avere un'idea attraverso l'aggregazione delle informazioni¹, ma non è abbastanza preciso e in alcuni casi può essere insufficiente².

  • Incoerenza degli standard dei dati. Che cosa succede se entrambi i progetti devono sapere dove si trova l'utente, ma il progetto 1 utilizza due lettere convenzionali, come CA , mentre il secondo usa il nome completo, come Canada ?

  • Diverse implementazioni di autenticazione. Ad esempio, il progetto 1 utilizza SHA256 , mentre il progetto 2 utilizza sale e SHA512 e il progetto 3 utilizza PBKDF2 ? Per risolvere questo problema, dovrai memorizzare ogni hash utilizzato, il che significa avere una tabella come questa:

    create table [People].[User]
    (
        ...
        [Mail] nvarchar(500) not null,
        [Salt] char(16) null, -- Salt used by project 1.
        [Hash] char(128) null, -- Hash used by project 1.
        [AlternateSalt] varchar(12) null, -- Salt used by project 4 and 5.
        [AlternateHash] char(64) null, -- Hash used by project 4 and 5.
        [ThirdHash] char(20) null, -- Hash (no salt) used by project 2.
        ... -- etc.
    )
    

    e fai controlli consecutivi, fino a trovarne uno buono.

    La cosa buona è che puoi consolidare progressivamente le password per gli utenti una volta che si sono autenticati. Ad esempio, se l'utente si autentica correttamente con SHA1 utilizzato dal quinto progetto, puoi calcolare e memorizzare l'hash PBKDF2 e salare e rimuovere l'hash SHA1 dal database.

    Dopo un anno o due, se ci sono ancora utenti che non hanno effettuato il logon per un po ', puoi inviare loro un messaggio di posta elettronica per dire che devono effettuare l'accesso se vogliono mantenere il loro account.

  • Password diverse. Il consolidamento può funzionare solo se l'utente è registrato in un progetto o se usa la stessa password per ogni progetto. Cosa succede se le password che usa per progetti diversi non sono le stesse? Hai ancora bisogno di mantenere la possibilità di accedere con diverse password.

  • Dati diversi. Se Vanessa Kelley ha detto che vive a Toronto per il progetto 1 e a Montreal per il progetto 2, quale è obsoleto?

Se le incongruenze sono troppo importanti, c'è il rischio che non sarai mai in grado di creare l'accesso unificato. Se ci sono poche o nessuna incongruenza, il compito sarà piuttosto facile.

Unificazione del processo

Una volta che hai unificato i dati, puoi fornire un processo comune per i cinque progetti. È possibile creare un servizio Web a cui si accederà tramite i cinque progetti oppure modificare tali progetti per accedere direttamente al database comune. Probabilmente sarebbe molto meglio usare un servizio web, invece di permettere a diverse applicazioni di accedere al database.

Se non puoi modificare i progetti originali, peccato. Puoi sincronizzare i dati tra i database, ma non è facile e non soggetto a errori.

Tuttavia, non si desidera che il processo di accesso comune utilizzi tutti e cinque i database. Non solo costa troppo in termini di risorse, ma rende anche l'intero processo dipendente da cinque database. Se uno di essi non funziona, il processo di accesso fallirebbe.

¹ Esempio: in base ai log, entrambi gli accessi sono stati effettuati dalla stessa macchina, uno alle 3:00 PM, il secondo alle 3:15 AM. Inoltre, le intestazioni del browser erano le stesse e il nome, il cognome e la data di nascita sono gli stessi.

² Esempio: se due accessi condividono lo stesso nome e cognome, non significa assolutamente nulla. Due persone possono condividere la stessa macchina o utilizzare lo stesso browser.

    
risposta data 20.05.2012 - 06:05
fonte
1

Vedi: link

Se hai intenzione di avere utenti in un database separato, va bene, ma devi capire che l'integrità referenziale non può essere garantita. Pertanto, devi fare del tuo meglio per mantenerlo (attraverso la logica dell'applicazione, la transazione distribuita, il trigger, ecc.) E devi mantenere i riferimenti remoti minimizzati.

In altre parole, se si ha una chiave esterna che fa riferimento a un database remoto, è meglio creare una tabella nel database locale che associ la chiave remota a una locale, in modo che le tabelle locali possano fare riferimento alla chiave locale piuttosto che direttamente a quella remota.

Ad esempio, supponiamo di avere una chiave remota chiamata "facebook_id" (ed è un GUID). Invece di fare riferimento direttamente a tutte le tue tabelle locali, crea una tabella denominata local_facebook_id, che memorizza un id localmente univoco insieme a facebook_id, quindi fai in modo che tutte le tue tabelle locali facciano riferimento al tuo id locale anziché direttamente a facebook_id. Il vantaggio è che ottieni l'integrità referenziale locale su un unico punto di riferimento.

Inoltre, puoi anche espandere la tabella local_facebook_id per memorizzare le credenziali e altre informazioni sul profilo, in modo che se il database remoto scompare o l'account dell'utente viene eliminato, gli utenti dell'applicazione potrebbero ancora accedere alla tabella local_facebook_id credenziali. Inoltre, conterrebbe informazioni sufficientemente significative su di loro che se l'account remoto viene cancellato definitivamente, i dati locali rimangono collegati a una fonte locale di informazioni personali significative (piuttosto che un semplice GUID senza significato), che potrebbe essere utilizzato anche in futuro -collega l'account locale a un nuovo facebook_id (ad es. tramite indirizzo email o altre informazioni identificative univoche).

    
risposta data 24.10.2013 - 00:23
fonte

Leggi altre domande sui tag