我正在尝试将新的incremental authorization用于已安装的应用,以便在保留现有范围的同时将范围添加到现有授权中。这是使用新的include_granted_scopes=true
参数完成的。但是,无论我尝试过什么,重新授权总是会完全覆盖范围。这是我用来演示我的问题的最小Bash PoC脚本:
client_id='716905662885.apps.googleusercontent.com' # throw away client_id (non-prod)
client_secret='CMVqIy_iQqBEMlzjYffdYM8A' # not really a secret
redirect_uri='urn:ietf:wg:oauth:2.0:oob'
while :
do
echo "Please enter a list of scopes (space separated) or CTRL+C to quit:"
read scope
# Form the request URL
# http://goo.gl/U0uKEb
auth_url="https://accounts.google.com/o/oauth2/auth?scope=$scope&redirect_uri=$redirect_uri&response_type=code&client_id=$client_id&approval_prompt=force&include_granted_scopes=true"
echo "Please go to:"
echo
echo "$auth_url"
echo
echo "after accepting, enter the code you are given:"
read auth_code
# swap authorization code for access token
# http://goo.gl/Mu9E5J
auth_result=$(curl -s https://accounts.google.com/o/oauth2/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d code=$auth_code \
-d client_id=$client_id \
-d client_secret=$client_secret \
-d redirect_uri=$redirect_uri \
-d grant_type=authorization_code)
access_token=$(echo -e "$auth_result" | \
grep -Po '"access_token" *: *.*?[^\\]",' | \
awk -F'"' '{ print $4 }')
echo
echo "Got an access token of:"
echo $access_token
echo
# Show information about our access token
info_result=$(curl -s --get https://www.googleapis.com/oauth2/v2/tokeninfo \
-H "Content-Type: application/json" \
-d access_token=$access_token)
current_scopes=$(echo -e "$info_result" | \
grep -Po '"scope" *: *.*?[^\\]",' | \
awk -F'"' '{ print $4 }')
echo "Our access token now allows the following scopes:"
echo $current_scopes | tr " " "\n"
echo
echo "Let's add some more!"
echo
done
该脚本只执行OAuth授权,然后打印出令牌当前有权使用的范围。从理论上讲,它应该每次都会继续添加范围,但实际上,范围列表每次都会被覆盖。因此,这个想法将在第一次运行时使用最小范围的email
,然后是下一次运行,更像是只读日历https://www.googleapis.com/auth/calendar.readonly
。每次都应该仅提示用户授权当前请求的范围,但生成的标记应该适用于所有范围,包括先前运行时授权的范围。
我尝试了一个新的client_id / secret,结果是一样的。我知道我可以再次包含已经授权的范围,但会提示用户输入所有范围,即使是已经授予的范围,我们都知道范围列表越长,用户接受的可能性就越小。
更新:在进一步测试期间,我注意到permissions for my app确实显示了每个增量授权的组合范围。我尝试在增量auth之后等待30秒左右,然后使用刷新令牌获取新的访问令牌,但该访问令牌仍然限于上一个授权的范围,而不是组合范围列表。
更新2:我还玩弄了原来的刷新令牌。刷新令牌仅获取允许原始范围的新访问令牌,不包括增量添加的范围。因此,有效include_granted_scopes=true
对令牌没有影响,旧的和新的刷新令牌继续有效但仅适用于其指定的范围。我无法获得“组合范围”刷新或访问令牌。
答案 0 :(得分:7)
Google的OAuth 2.0服务不支持已安装/原生应用的增量身份验证;它只适用于web server case。他们的文件被打破了。
答案 1 :(得分:1)
尝试向第二个请求添加一个完整的范围列表,您可以在其中交换访问令牌的授权码。奇怪的是,scope
参数doesn't seem to be documented,但它存在于google-api-java-client生成的请求中。例如:
code=foo&grant_type=authorization_code
&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fmyapp%2FoauthCallback
&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fplus.me+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fplus.stream.write
在web server scenario中,当include_granted_scopes
设置为true时,将返回已授予范围的完整列表以及授权码。这是链接文档中似乎缺少的另一点信息。
编辑1 在我们的Java应用程序中包含代码交换请求中的作用域的完整列表,但我刚刚尝试了原始脚本而没有修改(客户端ID /机密除外)它工作得很好(只编辑了ID和令牌):
$ bash tokens.sh
Please enter a list of scopes (space separated) or CTRL+C to quit:
https://www.googleapis.com/auth/userinfo.profile
Please go to:
https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/userinfo.profile&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code&client_id=189044568151-4bs2mcotfi2i3k6qp7vq8c6kbmkp2rf8.apps.googleusercontent.com&approval_prompt=force&include_granted_scopes=true
after accepting, enter the code you are given:
4/4qXGQ6Pt5QNYqdEuOudzY5G0ogru.kv_pt5Hlwq8UYKs_1NgQtlUFsAJ_iQI
Got an access token of:
ya29.1.AADtN_XIt8uUZ_zGZEZk7l9KuNQl9omr2FRXYAqf67QF92KqfvXliYQ54ffg_3E
Our access token now allows the following scopes:
https://www.googleapis.com/auth/userinfo.profile
https://www.googleapis.com/auth/userinfo.email
https://www.googleapis.com/auth/plus.me
https://www.googleapis.com/auth/plus.circles.read
您可以看到先前授予的范围包括在内......