Batasi Email Masuk dengan Google OAuth2.0 ke Nama Domain Tertentu

90

Sepertinya saya tidak dapat menemukan dokumentasi apa pun tentang cara membatasi login ke aplikasi web saya (yang menggunakan OAuth2.0 dan Google API) untuk hanya menerima permintaan autentikasi dari pengguna dengan email pada nama domain tertentu atau kumpulan nama domain. Saya ingin memasukkan ke daftar putih, bukan daftar hitam.

Adakah yang punya saran tentang cara melakukan ini, dokumentasi tentang metode yang diterima secara resmi untuk melakukannya, atau solusi yang mudah dan aman?

Sebagai catatan, saya tidak mengetahui info apa pun tentang pengguna hingga mereka mencoba masuk melalui autentikasi OAuth Google. Yang saya terima kembali adalah info pengguna dasar dan email.

paradox870
sumber
3
Saya sedang meneliti ini juga. Saya memiliki aplikasi yang saya inginkan agar hanya dapat diakses oleh orang yang memiliki akun di domain Google Apps for Business kami. Penerapan Google OpenID mungkin lebih sesuai untuk kita berdua ...
Aaron Bruce
1
Bagaimana cara menerapkan login pengguna domain menggunakan google sdk dan c #?
pengguna1021583
1
Tolong bisakah seseorang melihat pertanyaan ini stackoverflow.com/questions/34220051/…
1
Tolong saya memiliki karunia oben untuk pertanyaan itu sehingga dapatkah seseorang membantu saya

Jawaban:

42

Jadi saya punya jawaban untuk Anda. Dalam permintaan oauth Anda dapat menambahkan "hd = domain.com" dan itu akan membatasi otentikasi ke pengguna dari domain itu (saya tidak tahu apakah Anda dapat melakukan beberapa domain). Anda dapat menemukan parameter hd yang didokumentasikan di sini

Saya menggunakan perpustakaan google api dari sini: http://code.google.com/p/google-api-php-client/wiki/OAuth2 jadi saya harus mengedit file /auth/apiOAuth2.php secara manual ke ini :

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

Sunting: Saya masih mengerjakan aplikasi ini dan menemukan ini, yang mungkin merupakan jawaban yang lebih tepat untuk pertanyaan ini. https://developers.google.com/google-apps/profiles/

Aaron Bruce
sumber
Saya tidak mengetahui parameter ini, dapatkah Anda menautkan ke tempat Anda mengetahuinya?
Jason Hall
Sayangnya saya harus mendapatkan infonya dari rekan saya, saya tidak menemukan ini di mana pun di dokumen google. Rekan kerja saya mengira dia menemukan referensi di spesifikasi OpenID dan mencobanya di sini di spesifikasi OpenAuth dan tampaknya berhasil. Gunakan dengan hati-hati Saya kira karena tampaknya fungsionalitas tidak berdokumen.
Aaron Bruce
31
Catatan Penting: Meskipun Anda menentukan hdparameter dalam createAuthUrlfungsi, Anda masih perlu memverifikasi bahwa pengguna masuk dengan alamat email domain Anda. Sangat mudah untuk mengubah parameter tautan untuk mengizinkan semua alamat email dan kemudian mendapatkan akses ke aplikasi Anda.
VictorKilo
1
Untuk Dokumentasi Google tentang hdpenggunaan parameter, lihat developers.google.com/identity/work/it-apps Dan referensi hdparameter URI dapat ditemukan developers.google.com/identity/protocols/… Dalam sinopsis, hdparam harus dilihat sebagai filter tampilan berbasis domain untuk Google Auth, tetapi masih harus divalidasi di sisi Anda.
Will B.
2
Hebat, Saat ini, dalam hdparameter, saya hanya dapat membatasi satu domain, Sekarang bagaimana jika saya ingin membatasi dua atau tiga domain?
Jay Patel
11

Sisi klien:

Dengan menggunakan auth2fungsi init, Anda dapat memberikan hosted_domainparameter untuk membatasi akun yang terdaftar di munculan masuk ke akun yang cocok dengan Anda hosted_domain. Anda dapat melihat ini dalam dokumentasi di sini: https://developers.google.com/identity/sign-in/web/reference

Sisi server:

Meskipun dengan daftar sisi klien yang dibatasi, Anda perlu memverifikasi bahwa id_tokendomain tersebut cocok dengan domain yang Anda tentukan. Untuk beberapa implementasi, ini berarti memeriksa hdatribut yang Anda terima dari google setelah memverifikasi token.

Contoh Full Stack:

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

Kode Server (menggunakan pustaka Node.js googles):

Jika Anda tidak menggunakan Node.js, Anda dapat melihat contoh lain di sini: 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();
        });
    });
};
Jordon Biondo
sumber
9

Saat menentukan penyedia Anda, berikan hash di bagian akhir dengan parameter 'hd'. Anda dapat membacanya di sini. https://developers.google.com/accounts/docs/OpenIDConnect#hd-param

Misalnya, untuk config / penginisialisasi / devise.rb

config.omniauth :google_oauth2, 'identifier', 'key', {hd: 'yourdomain.com'}
Kosmonaut
sumber
1
Ini dengan mudah dapat dielakkan dengan memberikan akses untuk masuk dengan domain lain. Ini hanya akan berfungsi untuk membatasi akun yang tersedia yang ditampilkan kepada pengguna.
homaxto
2

Inilah yang saya lakukan dengan menggunakan paspor di node.js. profileadalah pengguna mencoba untuk masuk.

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

Kemudian buat logika untuk mencari beberapa domain, bukan hanya satu. Saya yakin metode ini aman karena 1. simbol '@' bukan karakter yang valid di bagian pertama atau kedua dari alamat email. Saya tidak dapat mengelabui fungsi tersebut dengan membuat alamat email seperti mike@[email protected]2. Dalam sistem login tradisional saya bisa, tetapi alamat email ini tidak pernah ada di Google. Jika ini bukan akun Google yang valid, Anda tidak dapat masuk.

mjoyce91
sumber
1

Sejak 2015 telah ada fungsi di perpustakaan untuk mengatur ini tanpa perlu mengedit sumber perpustakaan seperti di solusi oleh aaron-bruce

Sebelum membuat url, panggil saja setHostedDomainKlien Google Anda

$client->setHostedDomain("HOSTED DOMAIN")
JBithell
sumber