Restringir o e-mail de login com o Google OAuth2.0 ao nome de domínio específico

Não consigo encontrar nenhuma documentação sobre como restringir o login ao meu aplicativo da web (que usa OAuth2.0 e APIs do Google) para aceitar apenas solicitações de autenticação de usuários com um e-mail em um nome de domínio específico ou um conjunto de nomes de domínio. Eu gostaria de whitelist em oposição à lista negra.

Alguém tem sugestões sobre como fazer isso, documentação sobre o método oficialmente aceito de fazê-lo ou um trabalho fácil e seguro?

Para o registro, eu não sei nenhuma informação sobre o usuário até que ele tente fazer o login através da autenticação OAuth do Google. Tudo que recebo de volta é a informação básica do usuário e o email.

Então eu tenho uma resposta para você. Na solicitação oauth, você pode adicionar “hd = domain.com” e restringirá a autenticação aos usuários desse domínio (não sei se você pode fazer vários domínios). Você pode encontrar o parâmetro hd documentado aqui

Estou usando as bibliotecas da API do Google aqui: http://code.google.com/p/google-api-php-client/wiki/OAuth2, então tive que editar manualmente o arquivo /auth/apiOAuth2.php para isso :

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"; } 

Edit: Eu ainda estou trabalhando neste aplicativo e encontrei isso, que pode ser a resposta mais correta para esta pergunta. https://developers.google.com/google-apps/profiles/

Ao definir seu provedor, passe um hash no final com o parâmetro ‘hd’. Você pode ler sobre isso aqui. https://developers.google.com/accounts/docs/OpenIDConnect#hd-param

Por exemplo, para config / initializers / devise.rb

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

Aqui está o que eu fiz usando o passaporte em node.js. profile é o usuário que está tentando efetuar login.

 //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); 

Em seguida, basta criar lógica para procurar vários domínios em vez de apenas um. Eu acredito que este método é seguro porque 1. o símbolo ‘@’ não é um caractere válido na primeira ou segunda parte de um endereço de e-mail. Eu não poderia enganar a function, criando um endereço de e-mail como mike@fake@google.com 2. Em um sistema de login tradicional, eu poderia, mas este endereço de e-mail nunca poderia existir no Google. Se não for uma conta do Google válida, você não poderá fazer login.

Lado do Cliente:

Usando a function auth2 init, você pode passar o parâmetro hosted_domain para restringir as contas listadas no pop-in de hosted_domain às que correspondem ao seu hosted_domain . Você pode ver isso na documentação aqui: https://developers.google.com/identity/sign-in/web/reference

Lado do servidor:

Mesmo com uma lista do lado do cliente restrita, você precisará verificar se o id_token corresponde ao domínio hospedado que você especificou. Para algumas implementações, isso significa verificar o atributo hd você recebe do google depois de verificar o token.

Exemplo de pilha completa:

Código da 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(); }); }); } }); }); 

Código do Servidor (usando a biblioteca googles Node.js):

Se você não estiver usando o Node.js, poderá ver outros exemplos aqui: 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(); }); }); };