Limita l'email di accesso con Google OAuth2.0 a un nome di dominio specifico


90

Non riesco a trovare alcuna documentazione su come limitare l'accesso alla mia applicazione web (che utilizza OAuth2.0 e le API di Google) per accettare solo richieste di autenticazione da utenti con un'e-mail su un nome di dominio specifico o un insieme di nomi di dominio. Vorrei inserire nella lista bianca invece che nella lista nera.

Qualcuno ha suggerimenti su come farlo, documentazione sul metodo ufficialmente accettato per farlo o un lavoro facile e sicuro?

Per la cronaca, non conosco alcuna informazione sull'utente finché non tenta di accedere tramite l'autenticazione OAuth di Google. Tutto quello che ricevo sono le informazioni utente di base e l'e-mail.


3
Sto facendo ricerche anche su questo. Ho un'app che desidero sia accessibile solo da persone che hanno un account sul nostro dominio Google Apps for Business. L'implementazione di Google OpenID potrebbe essere più appropriata per entrambi ...
Aaron Bruce

1
Come posso implementare l'accesso utente di dominio utilizzando Google SDK e C #?
user1021583

1
Si prega di qualcuno può sguardo a questa domanda stackoverflow.com/questions/34220051/...

1
Per favore, ho una taglia oben su questa domanda, quindi qualcuno può aiutarmi

Risposte:


42

Quindi ho una risposta per te. Nella richiesta oauth puoi aggiungere "hd = dominio.com" e limiterà l'autenticazione agli utenti di quel dominio (non so se puoi fare più domini). Puoi trovare il parametro hd documentato qui

Sto usando le librerie API di Google da qui: http://code.google.com/p/google-api-php-client/wiki/OAuth2 quindi ho dovuto modificare manualmente il file /auth/apiOAuth2.php in questo :

public function createAuthUrl($scope) {
    $params = array(
        'response_type=code',
        'redirect_uri=' . urlencode($this->redirectUri),
        'client_id=' . urlencode($this->clientId),
        'scope=' . urlencode($scope),
        'access_type=' . urlencode($this->accessType),
        'approval_prompt=' . urlencode($this->approvalPrompt),
        'hd=domain.com'
    );

    if (isset($this->state)) {
        $params[] = 'state=' . urlencode($this->state);
    }
    $params = implode('&', $params);
    return self::OAUTH2_AUTH_URL . "?$params";
}

Modifica: sto ancora lavorando su questa app e ho trovato questa, che potrebbe essere la risposta più corretta a questa domanda. https://developers.google.com/google-apps/profiles/


Non ero a conoscenza di questo parametro, puoi collegarmi a dove l'hai scoperto?
Jason Hall

Purtroppo ho dovuto ottenere le informazioni da un mio collega, non le ho trovate da nessuna parte nei documenti di Google. Il mio collega pensa di aver trovato il riferimento nella specifica OpenID e l'ha provato qui nella specifica OpenAuth e sembra funzionare. Usare con cautela suppongo poiché sembra essere una funzionalità non documentata.
Aaron Bruce

31
Nota importante: anche se stai specificando un hdparametro nella createAuthUrlfunzione, dovrai comunque verificare che l'utente acceda con il tuo indirizzo email di dominio. È molto facile modificare il parametro del collegamento per consentire a tutti gli indirizzi e-mail e successivamente ottenere l'accesso alla tua applicazione.
VictorKilo

1
Per la documentazione di Google hdsull'utilizzo dei parametri vedere developers.google.com/identity/work/it-apps E il riferimento del hdparametro URI può essere trovato developers.google.com/identity/protocols/… Nella sinossi, il hdparametro dovrebbe essere visto come un filtro di visualizzazione basato sul dominio per il lato Google Auth, ma dovrebbe comunque essere convalidato dalla tua parte.
fyrye

2
Ottimo, Attualmente, in base ai hdparametri, posso limitare solo un dominio, ora cosa succede se voglio limitare due o tre domini?
Jay Patel

11

Dalla parte del cliente:

Utilizzando la auth2funzione init, puoi passare il hosted_domainparametro per limitare gli account elencati nel popup di accesso a quelli corrispondenti al tuo hosted_domain. Puoi vederlo nella documentazione qui: https://developers.google.com/identity/sign-in/web/reference

Lato server:

Anche con un elenco lato client limitato, dovrai verificare che id_tokencorrisponda al dominio ospitato specificato. Per alcune implementazioni questo significa controllare l' hdattributo che ricevi da google dopo aver verificato il token.

Esempio di stack completo:

Codice Web:

gapi.load('auth2', function () {
    // init auth2 with your hosted_domain
    // only matching accounts will show up in the list or be accepted
    var auth2 = gapi.auth2.init({
        client_id: "your-client-id.apps.googleusercontent.com",
        hosted_domain: 'your-special-domain.com'
    });

    // setup your signin button
    auth2.attachClickHandler(yourButtonElement, {});

    // when the current user changes
    auth2.currentUser.listen(function (user) {
        // if the user is signed in
        if (user && user.isSignedIn()) {
            // validate the token on your server,
            // your server will need to double check that the
            // `hd` matches your specified `hosted_domain`;
            validateTokenOnYourServer(user.getAuthResponse().id_token)
                .then(function () {
                    console.log('yay');
                })
                .catch(function (err) {
                    auth2.then(function() { auth2.signOut(); });
                });
        }
    });
});

Codice server (utilizzando la libreria Node.js di googles):

Se non utilizzi Node.js, puoi visualizzare altri esempi qui: https://developers.google.com/identity/sign-in/web/backend-auth

const GoogleAuth = require('google-auth-library');
const Auth = new GoogleAuth();
const authData = JSON.parse(fs.readFileSync(your_auth_creds_json_file));
const oauth = new Auth.OAuth2(authData.web.client_id, authData.web.client_secret);

const acceptableISSs = new Set(
    ['accounts.google.com', 'https://accounts.google.com']
);

const validateToken = (token) => {
    return new Promise((resolve, reject) => {
        if (!token) {
            reject();
        }
        oauth.verifyIdToken(token, null, (err, ticket) => {
            if (err) {
                return reject(err);
            }
            const payload = ticket.getPayload();
            const tokenIsOK = payload &&
                  payload.aud === authData.web.client_id &&
                  new Date(payload.exp * 1000) > new Date() &&
                  acceptableISSs.has(payload.iss) &&
                  payload.hd === 'your-special-domain.com';
            return tokenIsOK ? resolve() : reject();
        });
    });
};

9

Quando definisci il tuo provider, passa un hash alla fine con il parametro 'hd'. Puoi leggerlo qui. https://developers.google.com/accounts/docs/OpenIDConnect#hd-param

Ad esempio, per config / initializers / devise.rb

config.omniauth :google_oauth2, 'identifier', 'key', {hd: 'yourdomain.com'}

1
Questo può essere facilmente aggirato dando accesso al login con altri domini. Funzionerà solo per limitare gli account disponibili mostrati all'utente.
homaxto

2

Ecco cosa ho fatto usando passport in node.js. profileè l'utente che sta tentando di accedere.

//passed, stringified email login
var emailString = String(profile.emails[0].value);
//the domain you want to whitelist
var yourDomain = '@google.com';
//check the x amount of characters including and after @ symbol of passed user login.
//This means '@google.com' must be the final set of characters in the attempted login 
var domain = emailString.substr(emailString.length - yourDomain.length);

//I send the user back to the login screen if domain does not match 
if (domain != yourDomain)
   return done(err);

Quindi crea solo la logica per cercare più domini invece di uno solo. Credo che questo metodo sia sicuro perché 1. il simbolo "@" non è un carattere valido nella prima o nella seconda parte di un indirizzo email. Non ho potuto ingannare la funzione creando un indirizzo email come mike@fake@google.com2. In un sistema di login tradizionale potrei, ma questo indirizzo email non potrebbe mai esistere in Google. Se non è un account Google valido, non puoi accedere.


1

Dal 2015 è disponibile una funzione nella libreria per impostarlo senza dover modificare il sorgente della libreria come nella soluzione alternativa di aaron-bruce

Prima di generare l'URL, chiama il setHostedDomaintuo client Google

$client->setHostedDomain("HOSTED DOMAIN")
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.