如何验证Google身份验证API访问令牌?

问题描述:

如何验证Google身份验证访问令牌?如何验证Google身份验证API访问令牌?

我需要以某种方式查询Google并询问:给定的访问令牌对于[[email protected]] Google帐户有效吗?

短版
很清楚如何通过Google Authentication Api :: OAuth Authentication for Web Applications提供的访问令牌可以用来然后从一系列谷歌服务请求数据。目前尚不清楚如何检查给定的访问令牌对于给定的Google帐户是否有效。我想知道如何。

长版本
我正在开发一个使用基于标记的身份验证的API。在提供有效的用户名+密码或从可用于验证的服务 N中提供第三方令牌时,将返回令牌。

其中一项第三方服务是Google,允许用户使用他们的Google帐户对我的服务进行身份验证。这将在以后扩展到包括雅虎帐户,可信的OpenID提供商等等。基于谷歌的访问

原理例如:

alt text http://webignition.net/images/figures/auth_figure002.png

的 'API' 实体是我的完全控制之下。 '公共接口'实体是任何基于网络或桌面的应用程序。一些公共接口在我的控制之下,其他的不会,而其他的我也许永远不会知道。

因此,我不能相信在步骤3中提供给API的令牌。它将随相应的Google帐户电子邮件地址一起提供。

我需要以某种方式查询Google并询问:此访问令牌是否对[email protected]有效

在这种情况下,[email protected]是Google帐户唯一标识符 - 用户用于登录其Google帐户的电子邮件地址。这不能被认为是Gmail地址 - 某人可以拥有Google帐户,而无需拥有Gmail帐户。

Google文档清楚地说明了如何使用访问令牌从多个Google服务中检索数据。似乎没有什么可以说明如何检查给定的访问令牌是否有效。

更新 该令牌对N个Google服务有效。我无法尝试使用Google服务的令牌作为验证方式,因为我不知道给定用户实际使用的所有Google服务的哪个子集。

此外,我永远不会使用Google身份验证访问令牌来访问任何Google服务,只是作为验证所谓的Google用户实际上是他们所说的人的手段。如果还有其他的方式,我很乐意尝试。

+0

什么特定的认证服务是这个问题(OAut h,AuthSub,安装的应用程序,...)?请提供更详细的链接。 – 2008-12-11 15:06:59

+0

@Martin v。Löwis:“Web应用程序的OAuth身份验证”服务 - 我已更新问题的开头部分以反映此问题。感谢您指出了这一点! – 2008-12-11 15:26:12

+0

关于谷歌密钥验证的有趣文章可能会提供更多见解http://groups.google.com/group/Google-Maps-API/msg/f9e3c5ad3cbda4d7 – dotjoe 2008-12-31 18:04:32

尝试进行有效的请求并检查无效的令牌响应。

谷歌无法回答你的问题,因为它不是“这个访问令牌有效吗?”这是令人信服的秘密。

我需要以某种方式查询Google并询问:该访问令牌是否对[email protected]有效?

不需要。您需要的只是从您的API域请求标准登录Federated Login for Google Account Users。只有在此之后,您才可以将“永久性用户ID”与“公共界面”中的一个进行比较。

在Google联合登录页面上使用领域的值来向用户标识请求网站。它也用于确定Google返回的持久用户标识的值。

所以你需要来自同一个域作为'公共接口'。

并且不要忘记用户需要确保您的API可以被信任;所以Google会询问用户是否允许您检查他的身份。

尝试使用您的令牌对https://www.google.com/accounts/AuthSubTokenInfo进行OAuth认证的请求。这仅记录在AuthSub中,但它也适用于OAuth。它不会告诉你该令牌是用于哪个用户,但它会告诉你它对哪些服务有效,并且如果令牌无效或已被撤销,请求将失败。

任意OAuth访问令牌不能用于身份验证,因为令牌的含义不在OAuth Core规范中。它可以用于单次使用或缩短到期时间窗口,或者可以提供用户不想提供的访问。它也是不透明的,获得它的OAuth消费者可能永远都看不到任何类型的用户标识符。

一个OAuth服务提供者和一个或多个消费者可以很容易地使用OAuth提供可验证的认证令牌,并且有提案和想法可以做到这一点,但任意服务提供者只会说OAuth Core无法提供此没有与消费者的其他协调。特定于Google的AuthSubTokenInfo REST方法与用户标识符关系密切,但也不合适,因为它可能使标记无效,或者标记可能过期。

如果您的Google ID是OpenId标识符,并且您的“公共界面”既可以是网络应用,也可以调用用户的浏览器,那么您应该使用Google的OpenID OP。

OpenID包括只发送用户到OP和得到一个签名的断言回来。互动完全是为了RP的利益。没有长寿命的令牌或其他用户特定的句柄可用于指示RP已成功通过OP对用户进行身份验证。

假设使用相同的用户代理,验证以前的身份验证与OpenID标识符的一种方法是只需再次执行身份验证。 OP应该能够在没有用户交互的情况下返回肯定的断言(例如,通过验证cookie或客户端证书)。 OP可以*地要求另一个用户交互,并且如果认证请求来自另一个域(我的OP让我可以选择在未来不进行交互的情况下重新认证这个特定的RP),可能会发生。而在Google的情况下,用户通过获取OAuth令牌的UI可能不会使用相同的会话标识符,因此用户必须重新进行身份验证。但无论如何,你都可以断言身份。

+0

Google已拒绝OpenID 2.0并将其禁用,以支持基于OAuth的OpenID Connect提供[可验证的id令牌](http://*.com/a/31597027/603516)。 – Vadzim 2015-07-23 20:12:18

function authenticate_google_OAuthtoken($user_id) 
{ 
    $access_token = google_get_user_token($user_id); // get existing token from DB 
    $redirecturl = $Google_Permissions->redirecturl; 
    $client_id  = $Google_Permissions->client_id; 
    $client_secret = $Google_Permissions->client_secret; 
    $redirect_uri = $Google_Permissions->redirect_uri; 
    $max_results = $Google_Permissions->max_results; 

    $url = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token='.$access_token; 
    $response_contacts = curl_get_responce_contents($url); 
    $response = (json_decode($response_contacts)); 

    if(isset($response->issued_to)) 
    { 
     return true; 
    } 
    else if(isset($response->error)) 
    { 
     return false; 
    } 
} 

对于用户检查,只是张贴 获得访问令牌的accessToken和发布,并得到响应

https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=accessToken 

你可以在浏览器的地址栏中尝试过,用httppost和java的响应也

响应会像

{ 
    "issued_to": "xxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com", 
    "audience": "xxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com", 
    "user_id": "xxxxxxxxxxxxxxxxxxxxxxx", 
    "scope": "https://www.googleapis.com/auth/userinfo.profile https://gdata.youtube.com", 
    "expires_in": 3340, 
    "access_type": "offline" 
    } 

范围是accessToken的给定权限。你可以检查的范围IDS在this link

下面是一个使用Guzzle一个例子:

/** 
* @param string $accessToken JSON-encoded access token as returned by \Google_Client->getAccessToken() or raw access token 
* @return array|false False if token is invalid or array in the form 
* 
* array (
* 'issued_to' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com', 
* 'audience' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com', 
* 'scope' => 'https://www.googleapis.com/auth/calendar', 
* 'expires_in' => 3350, 
* 'access_type' => 'offline', 
*) 
*/ 
public static function tokenInfo($accessToken) { 
    if(!strlen($accessToken)) { 
     return false; 
    } 

    if($accessToken[0] === '{') { 
     $accessToken = json_decode($accessToken)->access_token; 
    } 

    $guzzle = new \GuzzleHttp\Client(); 

    try { 
     $resp = $guzzle->get('https://www.googleapis.com/oauth2/v1/tokeninfo', [ 
      'query' => ['access_token' => $accessToken], 
     ]); 
    } catch(ClientException $ex) { 
     return false; 
    } 

    return $resp->json(); 
} 

Google oauth code flow response除了access_token也返回id_token包含用于以加密形式验证信息是有用的。

让ID标记有用的一件事是,您可以通过 将它们传递给应用程序的不同组件。这些组件可以使用ID令牌作为轻量认证机制,认证应用程序和用户的 。但是,在使用ID 令牌中的信息或依赖它作为用户已认证的断言之前,您必须先验证它。

ID令牌的验证需要以下几个步骤:

  • 验证ID令牌是正确与合适的谷歌公共密钥签署了JWT。
  • 验证ID令牌中的aud值等于您应用的客户端ID。
  • 验证ID令牌中的iss值等于accounts.google.com或https://accounts.google.com
  • 验证ID令牌的到期时间(exp)未通过。
  • 如果您在请求中传递了一个hd参数,请验证该ID令牌具有与您的Google Apps托管域匹配的hd声明。

https://developers.google.com/identity/protocols/OpenIDConnect#validatinganidtoken链接具有验证ID令牌的代码示例。

另请参阅https://security.stackexchange.com/questions/37818/why-use-openid-connect-instead-of-plain-oauth

好吧,大多数答案是有效的,但不完全正确。智威汤逊的想法是,您可以验证令牌,而无需每次联系发行人。您必须检查id并使用用于签署令牌的Google证书的已知公钥验证令牌的签名。

看到下一篇文章为什么以及如何做到这一点。

http://ncona.com/2015/02/consuming-a-google-id-token-from-a-server/

您可以使用此端点验证谷歌认证访问令牌:

https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=<access_token> 

这是谷歌V3的OAuth的accessToken验证的端点,您可以从下面谷歌文档是指:(在OAUTH 2.0 ENDPOINTS标签)

https://developers.google.com/identity/protocols/OAuth2UserAgent#validate-access-token