Hạn chế Email đăng nhập bằng Google OAuth2.0 đối với tên miền cụ thể


90

Dường như tôi không thể tìm thấy bất kỳ tài liệu nào về cách hạn chế đăng nhập vào ứng dụng web của mình (ứng dụng này sử dụng API OAuth2.0 và Google) để chỉ chấp nhận các yêu cầu xác thực từ người dùng bằng email trên một tên miền cụ thể hoặc tập hợp các tên miền. Tôi muốn đưa vào danh sách trắng thay vì danh sách đen.

Có ai có đề xuất về cách thực hiện việc này, tài liệu về phương pháp được chấp nhận chính thức để làm như vậy, hoặc một công việc dễ dàng, an toàn xung quanh không?

Đối với hồ sơ, tôi không biết bất kỳ thông tin nào về người dùng cho đến khi họ cố gắng đăng nhập thông qua xác thực OAuth của Google. Tất cả những gì tôi nhận lại là thông tin người dùng cơ bản và email.


3
Tôi cũng đang nghiên cứu điều này. Tôi có một ứng dụng mà tôi muốn chỉ những người có tài khoản trên google apps dành cho miền doanh nghiệp của chúng tôi mới có thể truy cập được. Việc thực hiện google OpenID có thể thích hợp hơn cho cả hai chúng ta ...
Aaron Bruce

1
Làm cách nào để triển khai đăng nhập người dùng miền bằng google sdk và c #?
user1021583

1
Vui lòng một số người có thể xem câu hỏi này stackoverflow.com/questions/34220051/…

1
Xin vui lòng tôi có một tiền thưởng oben về câu hỏi mà rất có thể một số một giúp tôi

Câu trả lời:


42

Vì vậy, tôi đã có câu trả lời cho bạn. Trong yêu cầu oauth, bạn có thể thêm "hd = domain.com" và nó sẽ hạn chế xác thực đối với người dùng từ miền đó (Tôi không biết liệu bạn có thể thực hiện nhiều miền hay không). Bạn có thể tìm thấy thông số hd được ghi lại ở đây

Tôi đang sử dụng các thư viện api của google từ đây: http://code.google.com/p/google-api-php-client/wiki/OAuth2 vì vậy tôi phải chỉnh sửa thủ công tệp /auth/apiOAuth2.php này :

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

Chỉnh sửa: Tôi vẫn đang làm việc trên ứng dụng này và nhận thấy đây, đây có thể là câu trả lời chính xác hơn cho câu hỏi này. https://developers.google.com/google-apps/profiles/


Tôi không biết về thông số này, bạn có thể liên kết đến nơi bạn tìm hiểu về nó không?
Jason Hall

Thật không may, tôi phải lấy thông tin từ một đồng nghiệp của mình, tôi không tìm thấy thông tin này ở bất kỳ đâu trong tài liệu của google. Đồng nghiệp của tôi nghĩ rằng anh ấy đã tìm thấy tham chiếu trong thông số OpenID và đã thử nó ở đây trong thông số OpenAuth và nó có vẻ hoạt động. Tôi cho rằng sử dụng một cách thận trọng vì nó có vẻ là chức năng không có giấy tờ.
Aaron Bruce

31
Lưu ý quan trọng: Mặc dù bạn đang chỉ định một hdtham số trong createAuthUrlhàm, bạn vẫn cần xác minh rằng người dùng đang đăng nhập bằng địa chỉ email miền của bạn. Rất dễ dàng thay đổi tham số liên kết để cho phép tất cả các địa chỉ email và sau đó có quyền truy cập vào ứng dụng của bạn.
VictorKilo

1
Đối với Tài liệu của Google về hdcách sử dụng tham số, hãy xem developer.google.com/identity/work/it-apps Và tham chiếu tham số hdURI có thể được tìm thấy developer.google.com/identity/protocols/… Trong phần tóm tắt, hdtham số phải là được xem như một bộ lọc hiển thị dựa trên miền cho phía Google Auth, nhưng vẫn nên được xác thực về phía bạn.
fyrye

2
Tuyệt vời, Hiện tại, trong hdtham số, tôi chỉ có thể hạn chế một tên miền, Bây giờ nếu tôi muốn hạn chế hai hoặc ba tên miền thì sao?
Jay Patel

11

Phía khách hàng:

Sử dụng auth2hàm init, bạn có thể chuyển hosted_domaintham số để hạn chế các tài khoản được liệt kê trên cửa sổ bật lên đăng nhập cho những tài khoản phù hợp với của bạn hosted_domain. Bạn có thể xem điều này trong tài liệu tại đây: https://developers.google.com/identity/sign-in/web/reference

Phía máy chủ:

Ngay cả với danh sách phía máy khách bị hạn chế, bạn sẽ cần xác minh rằng các id_tokentên miền khớp với miền được lưu trữ mà bạn đã chỉ định. Đối với một số triển khai, điều này có nghĩa là kiểm tra hdthuộc tính bạn nhận được từ google sau khi xác minh mã thông báo.

Ví dụ về ngăn xếp đầy đủ:

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

Mã máy chủ (sử dụng thư viện Node.js của googles):

Nếu không sử dụng Node.js, bạn có thể xem các ví dụ khác tại đây: 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();
        });
    });
};

9

Khi xác định nhà cung cấp của bạn, hãy chuyển vào một hàm băm ở cuối với tham số 'hd'. Bạn có thể đọc về điều đó ở đây. https://developers.google.com/accounts/docs/OpenIDConnect#hd-param

Ví dụ: cho config / khởi tạo / devise.rb

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

1
Điều này có thể dễ dàng bị phá vỡ khi cấp quyền truy cập để đăng nhập với các miền khác. Nó sẽ chỉ hoạt động để giới hạn các tài khoản có sẵn được hiển thị cho người dùng.
homaxto

2

Đây là những gì tôi đã làm khi sử dụng passport trong node.js. profilelà người dùng đang cố gắng đăng nhập.

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

Sau đó, chỉ cần tạo logic để tìm kiếm nhiều tên miền thay vì chỉ một. Tôi tin rằng phương pháp này an toàn vì 1. ký hiệu '@' không phải là ký tự hợp lệ trong phần đầu tiên hoặc phần thứ hai của địa chỉ email. Tôi không thể đánh lừa chức năng bằng cách tạo một địa chỉ email như mike@fake@google.com2. Trong hệ thống đăng nhập truyền thống, tôi có thể làm được, nhưng địa chỉ email này không bao giờ có thể tồn tại trong Google. Nếu đó không phải là tài khoản Google hợp lệ, bạn không thể đăng nhập.


1

Kể từ năm 2015 đã có một chức năng trong thư viện để thiết lập điều này mà không cần chỉnh sửa nguồn thư viện như trong giải pháp thay thế của aaron-bruce

Trước khi tạo url, chỉ cần gọi đến setHostedDomainKhách hàng Google của bạn

$client->setHostedDomain("HOSTED DOMAIN")
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.