Ограничить адрес электронной почты с помощью Google OAuth2.0 до определенного имени домена
Я не могу найти какую-либо документацию о том, как ограничить вход в мое веб-приложение (которое использует OAuth2.0 и API Google), чтобы принимать только запросы на аутентификацию от пользователей с электронной почтой по определенному доменному имени или набору доменные имена. Я бы хотел, чтобы белый список, а не черный список.
Есть ли у кого-нибудь предложения по тому, как это сделать, документация по официально принятому методу этого или простая и безопасная работа?
Для записи я не знаю никакой информации о пользователе, пока не попытается войти в систему через проверку подлинности Google OAuth. Все, что я получаю, это основная информация пользователя и электронная почта.
Ответы
Ответ 1
Итак, у меня есть ответ для вас. В запросе oauth вы можете добавить "hd = domain.com", и это ограничит аутентификацию для пользователей из этого домена (я не знаю, можете ли вы делать несколько доменов). Вы можете найти hd-параметр, зарегистрированный здесь
Я использую библиотеки google api отсюда: http://code.google.com/p/google-api-php-client/wiki/OAuth2, поэтому мне пришлось вручную отредактировать файл /auth/apiOAuth 2.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/
Ответ 2
При определении вашего провайдера передайте хэш в конце с параметром "hd". Вы можете прочитать об этом здесь. https://developers.google.com/accounts/docs/OpenIDConnect#hd-param
Например, для config/initializers/devise.rb
config.omniauth :google_oauth2, 'identifier', 'key', {hd: 'yourdomain.com'}
Ответ 3
Вот что я сделал, используя паспорт в 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. символ "@" не является допустимым символом в первой или второй части адреса электронной почты. Я не мог обмануть эту функцию, создав адрес электронной почты, например [email protected]@google.com
2. В традиционной системе регистрации я мог, но этот адрес электронной почты никогда не существовал в Google. Если это не действительная учетная запись Google, вы не можете войти в систему.
Ответ 4
Сторона клиента:
Используя функцию auth2
init, вы можете передать параметр 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();
});
});
};