Google OAuth2.0으로 로그인 이메일을 특정 도메인 이름으로 제한


90

특정 도메인 이름 또는 도메인 이름 집합에 대한 이메일이있는 사용자의 인증 요청 만 수락하도록 내 웹 애플리케이션 (OAuth2.0 및 Google API 사용)에 대한 로그인을 제한하는 방법에 대한 문서를 찾을 수없는 것 같습니다. 블랙리스트가 아닌 화이트리스트를 작성하고 싶습니다.

누구든지이를 수행하는 방법에 대한 제안, 공식적으로 승인 된 방법에 대한 문서 또는 쉽고 안전한 해결 방법이 있습니까?

기록을 위해 사용자가 Google의 OAuth 인증을 통해 로그인을 시도 할 때까지 사용자에 대한 정보를 알지 못합니다. 내가받는 것은 기본 사용자 정보와 이메일뿐입니다.


3
나는 이것도 연구하고 있습니다. 비즈니스 용 Google 앱 도메인에 계정이있는 사용자 만 액세스 할 수있는 앱이 있습니다. 구글 오픈 ID 구현은 ... 우리 모두에게 더 적합 할 수있다
아론 브루스

1
Google SDK 및 C #을 사용하여 도메인 사용자 로그인을 구현하려면 어떻게해야합니까?
user1021583

1
이 질문을 한 번 봐주세요 stackoverflow.com/questions/34220051/…

1
제발 그 질문에 대한 현상금이있어서

답변:


42

그래서 나는 당신을위한 대답을 가지고 있습니다. oauth 요청에서 "hd = domain.com"을 추가하면 해당 도메인의 사용자로 인증이 제한됩니다 (여러 도메인을 수행 할 수 있는지 모르겠습니다). 여기에 설명 된 hd 매개 변수를 찾을 수 있습니다.

http://code.google.com/p/google-api-php-client/wiki/OAuth2 에서 Google API 라이브러리를 사용하고 있으므로 /auth/apiOAuth2.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/


이 매개 변수를 인식하지 못했습니다. 발견 한 위치로 링크 할 수 있습니까?
Jason Hall

안타깝게도 동료로부터 정보를 얻어야했지만 Google 문서 어디에서도이 정보를 찾지 못했습니다. 내 동료는 그가 OpenID 사양에서 참조를 찾은 것으로 생각하고 여기 OpenAuth 사양에서 시도해 보았고 작동하는 것 같습니다. 문서화되지 않은 기능으로 보이므로주의해서 사용하십시오.
Aaron Bruce

31
중요 참고 : 함수 hd에서 매개 변수를 지정하더라도 createAuthUrl사용자가 도메인 이메일 주소로 로그인하고 있는지 확인해야합니다. 링크 매개 변수를 변경하여 모든 이메일 주소를 허용하고 이후에 애플리케이션에 대한 액세스 권한을 얻는 것은 매우 쉽습니다.
VictorKilo 2013

1
hd매개 변수 사용 에 대한 Google 문서는 developers.google.com/identity/work/it-apps를 참조하세요. hdURI 매개 변수에 대한 참조는 developers.google.com/identity/protocols/… 에서 찾을 수 있습니다 . 요약 에서 매개 변수는 다음과 hd같아야합니다. Google 인증 측에 대한 도메인 기반 디스플레이 필터로 보이지만 여전히 사용자 측에서 유효성을 검사해야합니다.
Will B.

2
좋습니다. 현재 hd매개 변수에서 하나의 도메인 만 제한 할 수 있습니다. 이제 두 개 또는 세 개의 도메인을 제한하려면 어떻게해야합니까?
Jay Patel

11

고객 입장에서:

auth2init 함수를 사용하면 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();
        });
    });
};

9

공급자를 정의 할 때 끝에 'hd'매개 변수와 함께 해시를 전달하십시오. 여기에서 그것에 대해 읽을 수 있습니다. https://developers.google.com/accounts/docs/OpenIDConnect#hd-param

예 : config / initializers / devise.rb의 경우

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

1
이것은 다른 도메인으로 로그인에 대한 액세스를 제공하여 쉽게 우회 할 수 있습니다. 사용자에게 표시되는 사용 가능한 계정을 제한하는 경우에만 작동합니다.
homaxto

2

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. '@'기호가 이메일 주소의 첫 번째 또는 두 번째 부분에서 유효한 문자가 아니기 때문입니다. mike@fake@google.com2 와 같은 이메일 주소를 만들어서 기능을 속일 수는 없었 습니다. 전통적인 로그인 시스템에서는 할 수 있었지만이 이메일 주소는 Google에 존재할 수 없었습니다. 유효한 Google 계정이 아닌 경우 로그인 할 수 없습니다.


1

2015 년부터 aaron-bruce 의 해결 방법 에서와 같이 라이브러리 소스를 편집 할 필요없이이를 설정 하는 기능 이 라이브러리에있었습니다.

URL을 생성하기 전에 setHostedDomainGoogle 클라이언트를 호출 하십시오.

$client->setHostedDomain("HOSTED DOMAIN")
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.