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

90

Ich kann anscheinend keine Dokumentation dazu finden, wie die Anmeldung auf meine Webanwendung (die OAuth2.0- und Google-APIs verwendet) beschränkt werden kann, um nur Authentifizierungsanforderungen von Benutzern mit einer E-Mail an einen bestimmten Domainnamen oder eine Reihe von Domainnamen zu akzeptieren. Ich möchte eine Whitelist anstelle einer Blacklist erstellen.

Hat jemand Vorschläge dazu, eine Dokumentation der offiziell anerkannten Methode oder eine einfache, sichere Lösung?

Für die Aufzeichnung kenne ich keine Informationen über den Benutzer, bis er versucht, sich über die OAuth-Authentifizierung von Google anzumelden. Alles, was ich zurückerhalte, sind die grundlegenden Benutzerinformationen und E-Mails.

paradox870
quelle
3
Ich recherchiere das auch. Ich habe eine App, auf die nur Personen zugreifen möchten, die ein Konto in unseren Google Apps für Unternehmen haben. Die Google OpenID-Implementierung ist möglicherweise für uns beide besser geeignet ...
Aaron Bruce
1
Wie kann ich die Anmeldung von Domänenbenutzern mit Google SDK und C # implementieren?
user1021583
1
Bitte kann jemand
1
Bitte ich habe ein Kopfgeld auf diese Frage, also kann mir

Antworten:

42

Also habe ich eine Antwort für dich. In der oauth-Anfrage können Sie "hd = domain.com" hinzufügen, wodurch die Authentifizierung auf Benutzer dieser Domain beschränkt wird (ich weiß nicht, ob Sie mehrere Domains ausführen können). Den hier dokumentierten HD-Parameter finden Sie hier

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

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

Bearbeiten: Ich arbeite noch an dieser App und habe diese gefunden, was möglicherweise die richtigere Antwort auf diese Frage ist. https://developers.google.com/google-apps/profiles/

Aaron Bruce
quelle
Dieser Parameter war mir nicht bekannt. Können Sie einen Link zu der Stelle erstellen, an der Sie davon erfahren haben?
Jason Hall
Leider musste ich die Informationen von einem meiner Kollegen erhalten, ich habe sie nirgendwo in den Google-Dokumenten gefunden. Mein Mitarbeiter glaubt, die Referenz in der OpenID-Spezifikation gefunden und hier in der OpenAuth-Spezifikation ausprobiert zu haben, und es scheint zu funktionieren. Ich nehme an, Sie sollten es mit Vorsicht verwenden, da es sich um eine undokumentierte Funktionalität handelt.
Aaron Bruce
30
Wichtiger Hinweis: Auch wenn Sie hdin der createAuthUrlFunktion einen Parameter angeben, müssen Sie dennoch überprüfen, ob sich der Benutzer mit Ihrer Domain-E-Mail-Adresse anmeldet. Es ist sehr einfach, den Link-Parameter zu ändern, um alle E-Mail-Adressen zuzulassen und anschließend Zugriff auf Ihre Anwendung zu erhalten.
VictorKilo
1
Für die Google - Dokumentation auf der hdSiehe Parameter Verwendung developers.google.com/identity/work/it-apps Und die Referenz der hdURI - Parameter gefunden wird developers.google.com/identity/protocols/... In Synopse, das hdsollte param sein Wird als domänenbasierter Anzeigefilter für die Google Auth-Seite angesehen, sollte jedoch weiterhin auf Ihrer Seite überprüft werden.
Fyrye
2
Großartig. Derzeit hdkann ich im Parameter nur eine Domain einschränken. Was ist nun, wenn ich zwei oder drei Domains einschränken möchte?
Jay Patel
11

Kundenseite:

Mit der auth2Init-Funktion können Sie den hosted_domainParameter übergeben, um die im Anmelde-Popup aufgelisteten Konten auf diejenigen zu beschränken, die Ihren entsprechen hosted_domain. Sie können dies in der Dokumentation hier sehen: https://developers.google.com/identity/sign-in/web/reference

Serverseite:

Selbst bei einer eingeschränkten clientseitigen Liste müssen Sie überprüfen, ob die Liste id_tokenmit der von Ihnen angegebenen gehosteten Domain übereinstimmt. Bei einigen Implementierungen bedeutet dies, dass Sie das hdAttribut überprüfen, das Sie von Google erhalten, nachdem Sie das Token überprüft haben.

Beispiel für einen vollständigen Stapel:

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();
        });
    });
};
Jordon Biondo
quelle
9

Übergeben Sie bei der Definition Ihres Providers am Ende einen Hash mit dem Parameter 'hd'. 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'}
Kosmonaut
quelle
1
Dies kann leicht umgangen werden, indem Zugriff auf die Anmeldung mit anderen Domänen gewährt wird. Dies funktioniert nur, um die verfügbaren Konten einzuschränken, die dem Benutzer angezeigt werden.
Homaxto
2

Folgendes habe ich mit dem Pass in node.js gemacht. profileist 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);

Erstellen Sie dann einfach eine Logik, um nach mehreren Domänen anstatt nur nach einer zu suchen. Ich glaube, diese Methode ist sicher, weil 1. das @ -Symbol im ersten oder zweiten Teil einer E-Mail-Adresse kein gültiges Zeichen ist. Ich konnte die Funktion nicht austricksen, indem ich eine E-Mail-Adresse wie mike@[email protected]2 erstellte. In einem herkömmlichen Anmeldesystem konnte ich, aber diese E-Mail-Adresse konnte in Google niemals existieren. Wenn es sich nicht um ein gültiges Google-Konto handelt, können Sie sich nicht anmelden.

mjoyce91
quelle
1

Seit 2015 gibt es in der Bibliothek eine Funktion , mit der dies festgelegt werden kann, ohne dass die Quelle der Bibliothek wie in der Problemumgehung bearbeitet werden muss von aaron-bruce

Rufen setHostedDomainSie vor dem Generieren der URL einfach Ihren Google Client an

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