Обмежте електронну адресу для входу за допомогою Google OAuth2.0 певним доменним іменем


90

Здається, я не можу знайти жодної документації про те, як обмежити вхід для мого веб-додатку (який використовує OAuth2.0 та API Google), щоб приймати лише запити на автентифікацію від користувачів, які мають електронну пошту на конкретне доменне ім’я або набір доменних імен. Я хотів би внести до білого списку, а не до чорного.

Хтось має пропозиції щодо того, як це зробити, документацію щодо офіційно прийнятого методу чи легку та безпечну роботу?

Для запису, я не знаю жодної інформації про користувача, поки він не спробує увійти через автентифікацію OAuth від Google. Я отримую лише основну інформацію про користувача та електронну пошту.


3
Я також досліджую це. У мене є програма, до якої я хочу, щоб до неї мали доступ лише люди, які мають обліковий запис у наших програмах Google для бізнесу. Реалізація Google OpenID може бути більш підходящою для нас обох ...
Аарон Брюс,

1
Як я можу реалізувати вхід користувача домену за допомогою google sdk та c #?
user1021583

1
Будь ласка , може хто - небудь поглянути на це питання stackoverflow.com/questions/34220051 / ...

1
Будь ласка, я маю нагороду oben з цього питання, тож хтось може мені допомогти

Відповіді:


42

Отже, я отримав для вас відповідь. У запиті oauth ви можете додати "hd = domain.com", і це обмежить аутентифікацію для користувачів із цього домену (я не знаю, чи можете ви робити кілька доменів). Ви можете знайти параметр hd, задокументований тут

Я використовую бібліотеки goi api звідси: http://code.google.com/p/google-api-php-client/wiki/OAuth2, тому мені довелося вручну редагувати файл /auth/apiOAuth2.php до цього :

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

Редагувати: Я все ще працюю над цим додатком і знайшов це, що може бути правильнішою відповіддю на це запитання. https://developers.google.com/google-apps/profiles/


Мені не було відомо про цей параметр. Чи можете Ви зробити посилання на те, де Ви про це дізналися?
Джейсон Холл,

На жаль, мені довелося отримати інформацію у свого колеги, я не знайшов цього ніде в документах google. Мій колега вважає, що знайшов посилання в специфікації OpenID і спробував його тут у специфікації OpenAuth, і, схоже, це працює. Я використовую з обережністю, оскільки, здається, це недокументована функціональність.
Аарон Брюс,

31
Важливе зауваження: Незважаючи на те, що ви вказуєте hdпараметр у createAuthUrlфункції, вам все одно доведеться перевірити, що користувач входить в систему з електронною адресою вашого домену. Змінити параметр посилання дуже легко, щоб дозволити всі адреси електронної пошти і згодом отримати доступ до вашої програми.
VictorKilo

1
Документацію Google щодо використання hdпараметрів див. Developers.google.com/identity/work/it-apps. І посилання на hdпараметр URI можна знайти developers.google.com/identity/protocols/ ... В конспекті hdпараметр повинен бути таким: розглядається як фільтр відображення на основі домену для сторони Google Auth, але все одно має бути перевірений на вашій стороні.
Will B.

2
Чудово, В даний час за hdпараметром я можу обмежити лише один домен. Що тепер, якщо я хочу обмежити два-три домени?
Jay Patel

11

Сторона клієнта:

Використовуючи функцію auth2init, ви можете передати hosted_domainпараметр, щоб обмежити облікові записи, перелічені у спливаючому вікні входу, тими, що відповідають вашим hosted_domain. Ви можете побачити це в документації тут: https://developers.google.com/identity/sign-in/web/reference

Сторона сервера:

Навіть із обмеженим списком на стороні клієнта, вам потрібно буде перевірити, чи id_tokenвідповідає вказаний вами розміщений домен. Для деяких реалізацій це означає перевірку hdатрибута, який ви отримуєте від google після перевірки маркера.

Приклад повного стеку:

Веб-код:

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

Код сервера (за допомогою бібліотеки googles Node.js):

Якщо ви не використовуєте Node.js, ви можете переглянути інші приклади тут: 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

Визначаючи свого провайдера, введіть хеш в кінці з параметром 'hd'. Ви можете прочитати про це тут. https://developers.google.com/accounts/docs/OpenIDConnect#hd-param

Наприклад, для config / initializers / devise.rb

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

1
Це можна легко обійти, надаючи доступ до входу з іншими доменами. Це буде працювати лише для обмеження доступних облікових записів, показаних користувачеві.
homaxto

2

Ось що я зробив, використовуючи паспорт у node.js. profile- це спроба користувача увійти в систему.

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

Тоді просто створіть логіку для пошуку кількох доменів, а не лише одного. Я вважаю, що цей метод безпечний, оскільки 1. символ '@' не є дійсним символом у першій чи другій частині адреси електронної пошти. Я не міг обдурити цю функцію, створивши електронну адресу типу mike@fake@google.com2. У традиційній системі входу я міг би, але ця електронна адреса ніколи не могла існувати в Google. Якщо це не дійсний обліковий запис Google, ви не можете ввійти.


1

З 2015 року в бібліотеці існує функція, яка встановлює це без необхідності редагувати джерело бібліотеки, як в обхідному шляху aaron-bruce

Перш ніж створювати URL-адресу, просто зателефонуйте setHostedDomainсвоєму клієнту Google

$client->setHostedDomain("HOSTED DOMAIN")
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.