12

Ho una piccola webapp Firebase personale che utilizza il database Firebase. Voglio proteggere (bloccare) questa app per qualsiasi utente da un singolo dominio specifico. Voglio autenticarsi con Google. Non sono chiaro come configurare le regole per dire "solo gli utenti di un singolo dominio specifico (ad esempio @foobar.com) possono leggere e scrivere su questo database".Come posso bloccare Firebase Database a qualsiasi utente da un dominio (email) specifico?

(Parte del problema che vedo: è difficile eseguire il bootstrap di un database con informazioni sufficienti per far funzionare questo caso. Devo conoscere l'email dell'utente al momento dell'autenticazione, ma l'oggetto auth non contiene email Sembra essere un problema uovo di gallina, perché ho bisogno di scrivere le regole di Firebase che fanno riferimento ai dati nel database, ma quei dati non esistono ancora perché il mio utente non può scrivere nel database.)

Se l'email auth fosse stata inviata, potrei scrivere facilmente le regole.

Grazie in anticipo!

+1

domanda: quando si dice bloccare da un singolo dominio, vuol dire bloccare fino a un singolo fornitore, come Google o ha letteralmente significa solo permette agli utenti di myDomain di accedere al tuo Firebase cioè test @ myDomain autenticato per password è ok, ma la cosa @ anotherDomain autenticata tramite google non è consentita. – Jay

+0

Voglio dire, "chiunque da @ foobar.com, come convalidato/autenticato da Google, può leggere e scrivere il database" –

+0

Hai davvero bisogno di una regola? A un certo punto l'utente deve inserire il proprio indirizzo email per poter accedere o creare il proprio account in primo luogo, quindi non è possibile analizzarlo al momento dell'inserimento e rifiutare ciò che non ha @ foobar.com come il dominio? – Jay

risposta

28

Se si sta utilizzando il nuovo Firebase, questo è ora possibile, dal momento che lo email è disponibile nelle regole di sicurezza.

Nelle regole di sicurezza è possibile accedere sia all'indirizzo email sia alla sua verifica, il che rende possibili grandi casi d'uso. Con queste regole, ad esempio solo, l'utente gmail verificato autenticato può scrivere il loro profilo:

{ 
    "rules": { 
    ".read": "auth != null", 
    "gmailUsers": { 
     "$uid": { 
     ".write": "auth.token.email_verified == true && 
        auth.token.email.matches(/.*@gmail.com$/)" 
     } 
    } 
    } 
} 

È possibile inserire queste regole nel Firebase Database console del vostro progetto.

+0

Grazie mille per l'aggiornamento! –

+1

https://firebase.google.com/docs/reference/security/database/#authtoken contiene la documentazione di ciò che è disponibile in "auth.token". –

+1

Sarebbe bello vedere un esempio di ciò che ha estratto '@ gmail.com' da una radice nel database, ad esempio' my_database/acceptable_domains/'nel caso in cui, ad esempio, volessero solo aprire la loro applicazione a una manciata di provider di posta elettronica. Come scuole e aziende autorizzate. – Hobbyist

2

ATTENZIONE: non fidatevi di questa risposta. Sono qui solo per la discussione.

tldr: Non penso sia possibile, senza eseguire il proprio server.

Ecco il mio tentativo finora:

{ 
    "rules": { 
    ".read": "auth.provider === 'google' && root.child('users').child(auth.uid).child('email').val().endsWith('@foobar.com')", 
    ".write": "auth.provider === 'google' && root.child('users').child(auth.uid).child('email').val().endsWith('@foobar.com')", 
    "users": { 
     "$user_id": { 
     ".write": "auth.provider === 'google' && $user_id === auth.uid && newData.child('email').val().endsWith('@foobar.com')" 
     } 
    } 
    } 
} 

Credo che quanto sopra scritto "permettono solo alle persone di creare un nuovo utente se sono autenticati da Google, sta tentando di scrivere nel nodo database per themselve ($user_id === auth.uid) e la loro posta elettronica termina su foobar.com ".

Tuttavia, è stato rilevato un problema: qualsiasi client Web può facilmente modificare la propria posta elettronica (utilizzando la console di sviluppo) prima che il messaggio venga inviato a Firebase. Quindi non possiamo fidarci dei dati della voce dell'utente quando vengono archiviati in Firebase.

Penso che l'unica cosa di cui ci possiamo fidare è l'oggetto auth nelle regole. L'oggetto auth viene popolato dal back-end di Firebase. E, sfortunatamente, l'oggetto auth non include l'indirizzo email.

Per la cronaca, sto inserendo il mio utente in questo modo:

function authDataCallback(authData) { 
    if (authData) { 
    console.log("User " + authData.uid + " is logged in with " + authData.provider + " and has displayName " + authData.google.displayName); 
    // save the user's profile into the database so we can list users, 
    // use them in Security and Firebase Rules, and show profiles 
    ref.child("users").child(authData.uid).set({ 
     provider: authData.provider, 
     name: getName(authData), 
     email: authData.google.email 
    }); 

Come si può essere in grado di immaginare, un utente determinato potrebbe sovrascrivere il valore di email qui (utilizzando i DevTools, per gli esempi) .

+0

Come hai effettivamente scoperto: le regole '.write' possono controllare chi può scrivere in una posizione e le regole' .validate' possono convalidare che quello che scrivono è un indirizzo email valido. Ma non c'è modo di verificare nelle regole di sicurezza che in realtà è l'indirizzo email dell'utente. Per questo è necessario eseguire un codice attendibile (in genere su un server) che scriverà questo indirizzo email verificato in una posizione (altrimenti di sola lettura) nel database. –

1

Ecco il codice che funziona bene con il mio database, ho impostato la regola che solo le email della mia azienda possono leggere e scrivere i dati del mio database Firebase.

{ 
    "rules": { 
    ".read": "auth.token.email.matches(/.*@yourcompany.com$/)", 


     ".write": "auth.token.email.matches(/.*@yourcompany.com$/)" 
     } 
    } 
0

Codice che funziona per me.

export class AuthenticationService { 

    user: Observable<firebase.User>; 

    constructor(public afAuth: AngularFireAuth) { 
     this.user = afAuth.authState; 
    } 

    login(){ 
     var provider = new firebase.auth.GoogleAuthProvider(); 
     provider.setCustomParameters({'hd': '<your domain>'}); 
     this.afAuth.auth.signInWithPopup(provider) 
     .then(response => { 
      let token = response.credential.accessToken; 
      //Your code. Token is now available. 
     }) 
    } 
} 
Problemi correlati