Nie mogę znaleźć żadnej dokumentacji na temat tego, jak ograniczyć logowanie do mojej aplikacji internetowej (która korzysta z OAuth2.0 i interfejsów API Google), aby akceptować tylko żądania uwierzytelnienia od użytkowników z adresem e-mail w określonej nazwie domeny lub zestawie nazw domen. Chciałbym umieścić na białej liście, a nie na czarnej liście.
Czy ktoś ma sugestie, jak to zrobić, dokumentację na temat oficjalnie przyjętej metody lub łatwe, bezpieczne obejście?
Dla przypomnienia, nie znam żadnych informacji o użytkowniku, dopóki nie spróbuje zalogować się za pomocą uwierzytelniania OAuth firmy Google. Otrzymuję tylko podstawowe informacje o użytkowniku i e-mail.
google-api
oauth-2.0
google-oauth
paradox870
źródło
źródło
Odpowiedzi:
Więc mam dla ciebie odpowiedź. W żądaniu oauth możesz dodać „hd = domain.com” i ograniczy to uwierzytelnianie do użytkowników z tej domeny (nie wiem, czy możesz zrobić wiele domen). Możesz znaleźć udokumentowany parametr hd tutaj
Używam bibliotek Google API stąd: http://code.google.com/p/google-api-php-client/wiki/OAuth2, więc musiałem ręcznie edytować plik /auth/apiOAuth2.php do tego :
Edycja: wciąż pracuję nad tą aplikacją i znalazłem to, co może być bardziej poprawną odpowiedzią na to pytanie. https://developers.google.com/google-apps/profiles/
źródło
hd
parametr wcreateAuthUrl
funkcji, nadal będziesz musiał sprawdzić, czy użytkownik loguje się przy użyciu adresu e-mail Twojej domeny. Bardzo łatwo jest zmienić parametr łącza, aby zezwolić na wszystkie adresy e-mail, a następnie uzyskać dostęp do aplikacji.hd
użycia parametrów znajduje się na developers.google.com/identity/work/it-apps . Odniesienie dohd
parametru URI można znaleźć developers.google.com/identity/protocols/… W skróciehd
parametr powinien być jest postrzegany jako filtr wyświetlania oparty na domenie po stronie Google Auth, ale nadal powinien zostać zweryfikowany po Twojej stronie.hd
parametrze mogę ograniczyć tylko jedną domenę, a co jeśli chcę ograniczyć dwie lub trzy domeny?Strona klienta:
Korzystając z
auth2
funkcji init, możesz przekazaćhosted_domain
parametr, aby ograniczyć konta wymienione w wyskakującym okienku logowania do tych, które pasują do Twojegohosted_domain
. Możesz to zobaczyć w dokumentacji tutaj: https://developers.google.com/identity/sign-in/web/referencePo stronie serwera:
Nawet w przypadku ograniczonej listy po stronie klienta musisz sprawdzić, czy
id_token
pasuje do określonej domeny hostowanej. W przypadku niektórych implementacji oznacza to sprawdzeniehd
atrybutu, który otrzymujesz od Google po zweryfikowaniu tokena.Przykład pełnego stosu:
Kod sieciowy:
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(); }); }); } }); });
Kod serwera (przy użyciu biblioteki googles Node.js):
Jeśli nie używasz Node.js, możesz zobaczyć inne przykłady tutaj: 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(); }); }); };
źródło
Definiując swojego dostawcę, podaj skrót na końcu z parametrem „hd”. Możesz o tym przeczytać tutaj. https://developers.google.com/accounts/docs/OpenIDConnect#hd-param
Np. Dla config / initializers / devise.rb
źródło
Oto, co zrobiłem, używając paszportu w node.js.
profile
to użytkownik próbujący się zalogować.Następnie stwórz logikę, aby szukać wielu domen zamiast tylko jednej. Uważam, że ta metoda jest bezpieczna, ponieważ 1. symbol „@” nie jest prawidłowym znakiem w pierwszej lub drugiej części adresu e-mail. Nie mogłem oszukać funkcji, tworząc adres e-mail taki jak
mike@[email protected]
2. W tradycyjnym systemie logowania mogłem, ale ten adres e-mail nigdy nie mógł istnieć w Google. Jeśli nie jest to prawidłowe konto Google, nie możesz się zalogować.źródło
Od 2015 roku w bibliotece istnieje funkcja umożliwiająca ustawienie tego bez konieczności edytowania źródła biblioteki, tak jak w obejściu przez aarona-bruce'a
Przed wygenerowaniem adresu URL po prostu zadzwoń
setHostedDomain
do swojego klienta Googleźródło