webentwicklung-frage-antwort-db.com.de

Beschränken Sie die Anmelde-E-Mail mit Google OAuth2.0 auf einen bestimmten Domänennamen

Ich kann anscheinend keine Dokumentation finden, wie die Anmeldung auf meine Webanwendung (die OAuth2.0 und Google APIs verwendet) beschränkt wird, um nur Authentifizierungsanfragen von Benutzern mit einer E-Mail an einen bestimmten Domänennamen oder einen Satz von Domänennamen anzunehmen. Ich möchte im Gegensatz zur schwarzen Liste eine Positivliste hinzufügen.

Hat jemand Vorschläge, wie dies getan wird, Dokumentation über die offiziell akzeptierte Methode oder eine einfache, sichere Lösung?

Für das Protokoll kenne ich keine Informationen über den Benutzer, bis er versucht, sich über die OAuth-Authentifizierung von Google anzumelden. Ich erhalte nur die grundlegenden Benutzerinformationen und E-Mail-Adressen.

78
paradox870

Ich habe also eine Antwort für dich. In der oauth-Anfrage können Sie "hd = domain.com" hinzufügen. Dadurch wird die Authentifizierung auf Benutzer dieser Domäne beschränkt (ich weiß nicht, ob Sie mehrere Domänen ausführen können). Hd-Parameter finden Sie dokumentiert hier

Ich verwende die Google-API-Bibliotheken von hier: http://code.google.com/p/google-api-php-client/wiki/OAuth2 . Daher musste ich/auth/apiOAuth2 manuell bearbeiten. PHP-Datei dazu:

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: Ich arbeite immer noch an dieser App und habe dies gefunden, was möglicherweise die richtige Antwort auf diese Frage ist. https://developers.google.com/google-apps/profiles/

40
Aaron Bruce

Bei der Definition Ihres Providers geben Sie am Ende einen Hash mit dem Parameter 'hd' ein. Das können Sie hier nachlesen. https://developers.google.com/accounts/docs/OpenIDConnect#hd-param

Zum Beispiel für config/initializers/devise.rb

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

Kundenseite:

Mit der auth2 init-Funktion können Sie den hosted_domain-Parameter übergeben, um die im Anmelde-Popup aufgeführten Konten auf die Konten zu beschränken, die Ihrem hosted_domain entsprechen. Sie finden dies in der Dokumentation hier: https://developers.google.com/identity/sign-in/web/reference

Serverseite:

Selbst bei einer eingeschränkten clientseitigen Liste müssen Sie überprüfen, ob der id_token der von Ihnen angegebenen gehosteten Domäne entspricht. Bei einigen Implementierungen bedeutet dies, dass Sie das hd-Attribut überprüfen, das Sie von Google erhalten, nachdem Sie das Token überprüft haben.

Full Stack Beispiel:

Webcode:

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

Servercode (unter Verwendung der googles Node.js-Bibliothek):

Wenn Sie Node.js nicht verwenden, können Sie hier weitere Beispiele anzeigen: 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();
        });
    });
};
3
Jordon Biondo

So habe ich Passport in node.js verwendet. profile ist der Benutzer, der versucht, sich anzumelden.

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

Dann erstellen Sie einfach eine Logik, um nach mehreren Domänen statt nur nach einer zu suchen. Ich glaube, dass diese Methode sicher ist, weil 1. das '@'-Symbol kein gültiges Zeichen im ersten oder zweiten Teil einer E-Mail-Adresse ist. Ich konnte die Funktion nicht täuschen, indem ich eine E-Mail-Adresse wie [email protected]@google.com 2 erstellte. In einem herkömmlichen Anmeldesystem könnte ich dies tun, aber diese E-Mail-Adresse könnte in Google niemals existieren. Wenn es kein gültiges Google-Konto ist, können Sie sich nicht anmelden.

2
mjoyce91

Seit 2015 gibt es eine Funktion in der Bibliothek , um dies einzustellen, ohne die Quelle der Bibliothek wie im Workaround von aaron-bruce bearbeiten zu müssen

Bevor Sie die URL generieren, rufen Sie einfach setHostedDomain für Ihren Google-Client auf

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