Limita le email di accesso con Google OAuth2.0 al nome di dominio specifico

Non riesco a trovare alcuna documentazione su come limitare il login alla mia applicazione web (che utilizza OAuth2.0 e le API di Google) per accettare solo richieste di autenticazione da parte degli utenti con un’e-mail su un nome di dominio specifico o un insieme di nomi di dominio. Vorrei fare la lista bianca rispetto alla lista nera.

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

Per la cronaca, non conosco informazioni sull’utente finché non tentano di accedere tramite l’autenticazione OAuth di Google. Tutto ciò che ricevo sono le informazioni e le e-mail dell’utente di base.

Quindi ho una risposta per te. Nella richiesta oauth puoi aggiungere “hd = dominio.com” e limiterà l’autenticazione agli utenti da quel dominio (non so se puoi fare più domini). Puoi trovare i parametri hd documentati qui

Sto usando le librerie di Google API da qui: http://code.google.com/p/google-api-php-client/wiki/OAuth2 quindi ho dovuto modificare manualmente il file /auth/apiOAuth2.php a 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 a questa app e ho trovato questa, che potrebbe essere la risposta più corretta a questa domanda. https://developers.google.com/google-apps/profiles/

Quando definisci il tuo provider, passa un hash alla fine con il parametro ‘hd’. Puoi leggere su questo 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'} 

Ecco cosa ho fatto usando il passaporto in node.js. profile è l’utente che tenta 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 basta creare 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 [email protected]@google.com 2. In un sistema di accesso tradizionale, potrei, ma questo indirizzo email non potrebbe mai esistere in Google. Se non è un account Google valido, non puoi effettuare il login.

Dalla parte del cliente:

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

Lato server:

Anche con un elenco limitato lato client è necessario verificare che id_token corrisponda al dominio ospitato specificato. Per alcune implementazioni questo significa controllare l’attributo hd che ricevi da google dopo aver verificato il token.

Esempio di pila completa:

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 stai utilizzando 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(); }); }); };