是否可以从同一个 Google Apps 域中获取所有用户?
Is it possible to get all users from the same Google Apps domain?
我需要实现以下场景:
- 用户使用他或她的 Google 凭据登录。
- 此后我的应用程序检查此用户是否正在使用 Google
应用。
- 如果他或她是,我的应用程序将读取同一个 Google 中的所有活动用户
应用域 (
com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload#getHostedDomain
).
它类似于 Facebook 上的 "Find your friends" 功能。在这种情况下,我想
查找所有使用相同 Google 应用程序域的人。
是否可以(在技术上和使用条款方面)?
更新 1(2017 年 8 月 28 日 20:00 MSK):
我试图获取所有使用访问令牌的用户的列表(下面代码片段中的gIdToken.payload.accessTokenHash
):
internal open fun createJsonFactory(): JsonFactory = JacksonFactory.getDefaultInstance()
internal open fun createTransport(): HttpTransport = GoogleNetHttpTransport.newTrustedTransport()
internal open fun createVerifier(httpTransport: HttpTransport, jsonFactory: JsonFactory): GoogleIdTokenVerifier {
return GoogleIdTokenVerifier.Builder(httpTransport, jsonFactory)
.setAudience(listOf(clientId))
.build()
}
val idToken = req.queryParams("idtoken")
val httpTransport = createTransport()
val jsonFactory = createJsonFactory()
val verifier = createVerifier(httpTransport, jsonFactory)
val gIdToken = verifier.verify(idToken)
if ((gIdToken != null) && (gIdToken.payload != null)) {
val credential = GoogleCredential().setAccessToken(gIdToken.payload.accessTokenHash)
val directory = Directory.Builder(httpTransport, jsonFactory, credential)
.setApplicationName("Google Auth Test")
.build()
try {
directory.users().list().setCustomer(gIdToken.payload.subject).execute()
}
catch (ex:Throwable) {
ex.printStackTrace()
}
}
当我 运行 directory.users().list().setCustomer(gIdToken.payload.subject).execute()
时,出现以下错误:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized
{
"code" : 401,
"errors" : [ {
"domain" : "global",
"location" : "Authorization",
"locationType" : "header",
"message" : "Invalid Credentials",
"reason" : "authError"
} ],
"message" : "Invalid Credentials"
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:146)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.interceptResponse(AbstractGoogleClientRequest.java:321)
我正在使用以下 Google 库:
<dependency>
<groupId>google-api-services</groupId>
<artifactId>admin-directory_v1</artifactId>
<version>1.22.0</version>
</dependency>
<dependency>
<groupId>com.google.gdata</groupId>
<artifactId>core</artifactId>
<version>1.47.1</version>
</dependency>
如何解决上述错误?
更新 2(2017 年 8 月 29 日 11:39 MSK): 尝试使用通讯录 API
尝试 1:联系人 API 供稿
import com.google.gdata.data.extensions.ContactFeed
fun readUsers2(gIdToken:GoogleIdToken, httpTransport: HttpTransport, jsonFactory:JsonFactory) {
val credential = GoogleCredential().setAccessToken(gIdToken.payload.accessTokenHash)
val service = ContactsService("Google Auth Test")
service.setOAuth2Credentials(credential)
val feedUrl = URL("https://www.googleapis.com/auth/contacts.readonly")
val resultFeed: ContactFeed = service.getFeed(feedUrl, ContactFeed::class.java)
}
结果:异常 "Unrecognized content type: text/plain"
com.google.gdata.client.Service#parseResponseData(com.google.gdata.data.ParseSource, com.google.gdata.wireformats.input.InputProperties, java.lang.Class<E>)
, 见
下面抛出语句。
private <E> E parseResponseData(ParseSource source, InputProperties inputProperties, Class<E> resultType) throws IOException, ServiceException {
Preconditions.checkNotNull("resultType", resultType);
AltFormat inputFormat = null;
String alt = inputProperties.getQueryParameter("alt");
if (alt != null) {
inputFormat = this.altRegistry.lookupName(alt);
}
if (inputFormat == null) {
inputFormat = this.altRegistry.lookupType(inputProperties.getContentType());
if (inputFormat == null) {
throw new ParseException("Unrecognized content type:" + inputProperties.getContentType());
}
}
尝试 2:联系人 API 查询
fun readUsers3(gIdToken:GoogleIdToken, httpTransport: HttpTransport, jsonFactory:JsonFactory) {
val credential = GoogleCredential().setAccessToken(gIdToken.payload.accessTokenHash)
val service = ContactsService("Google Auth Test")
service.setOAuth2Credentials(credential)
val feedUrl = URL("https://www.googleapis.com/auth/contacts.readonly")
val query = Query(feedUrl)
val resultFeed = service.query(query, ContactFeed::class.java)
}
结果:与尝试 2 中的异常相同。
更新 3(2017 年 8 月 29 日 13:04 MSK):
我尝试使用 API Explorer.
获取用户列表
我收到 403
错误。详情如下。
要求:
GET https://www.googleapis.com/admin/directory/v1/users?domain={MYDOMAIN}&fields=users(emails%2Cid%2Cname)&key={YOUR_API_KEY}
回复:
403
- Show headers -
{
"error": {
"errors": [
{
"domain": "global",
"reason": "forbidden",
"message": "Not Authorized to access this resource/api"
}
],
"code": 403,
"message": "Not Authorized to access this resource/api"
}
}
更新 4(30.08.2017 13:19 MSK):
最后,我设法摆脱了身份验证和授权错误(在
测试安装 G 套件应用程序)。
但是,现在以下调用 return 一个空的用户列表(没有错误)。
val directory = Directory.Builder(
NetHttpTransport(),
JacksonFactory.getDefaultInstance(),
credential)
.setApplicationName("Google Auth Test")
.build()
val users = directory.users().list()
检查此 documentation to retrieve all users in the same domain, use the following GET
request and include the authorization described in Authorize requests。为了便于阅读,此示例使用行 returns:
GET https://www.googleapis.com/admin/directory/v1/users
?domain=primary domain name&pageToken=token for next results page
&maxResults=max number of results per page
&orderBy=email, givenName, or familyName
&sortOrder=ascending or descending
&query=email, givenName, or familyName:the query's value*
对于请求和响应属性,您可能需要使用 Users: list method wherein it retrieves a paginated list of either deleted users or all users in a domain. This request requires authorization with at least one of the following scopes (read more about authentication and authorization).
https://www.googleapis.com/auth/admin.directory.user.readonly
https://www.googleapis.com/auth/admin.directory.user
您需要从用户那里获得足够的权限才能获取域中所有用户的列表。此外,它只有在登录用户是域的超级管理员时才有效。
您可以获得权限列表here。
此问题与Google API/get directory contacts
相关
我在这里发布一个答案,因为这个答案更 google 友好:
管理员目录 Users:list 资源允许在没有管理员权限的情况下列出公司目录。
只需确保将 viewType
设置为 domain_public
即可:
https://www.googleapis.com/admin/directory/v1/users?customer=my_customer&viewType=domain_public
https://www.googleapis.com/auth/admin.directory.user.readonly
的范围应该足够了。
我需要实现以下场景:
- 用户使用他或她的 Google 凭据登录。
- 此后我的应用程序检查此用户是否正在使用 Google 应用。
- 如果他或她是,我的应用程序将读取同一个 Google 中的所有活动用户
应用域 (
com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload#getHostedDomain
).
它类似于 Facebook 上的 "Find your friends" 功能。在这种情况下,我想 查找所有使用相同 Google 应用程序域的人。
是否可以(在技术上和使用条款方面)?
更新 1(2017 年 8 月 28 日 20:00 MSK):
我试图获取所有使用访问令牌的用户的列表(下面代码片段中的gIdToken.payload.accessTokenHash
):
internal open fun createJsonFactory(): JsonFactory = JacksonFactory.getDefaultInstance()
internal open fun createTransport(): HttpTransport = GoogleNetHttpTransport.newTrustedTransport()
internal open fun createVerifier(httpTransport: HttpTransport, jsonFactory: JsonFactory): GoogleIdTokenVerifier {
return GoogleIdTokenVerifier.Builder(httpTransport, jsonFactory)
.setAudience(listOf(clientId))
.build()
}
val idToken = req.queryParams("idtoken")
val httpTransport = createTransport()
val jsonFactory = createJsonFactory()
val verifier = createVerifier(httpTransport, jsonFactory)
val gIdToken = verifier.verify(idToken)
if ((gIdToken != null) && (gIdToken.payload != null)) {
val credential = GoogleCredential().setAccessToken(gIdToken.payload.accessTokenHash)
val directory = Directory.Builder(httpTransport, jsonFactory, credential)
.setApplicationName("Google Auth Test")
.build()
try {
directory.users().list().setCustomer(gIdToken.payload.subject).execute()
}
catch (ex:Throwable) {
ex.printStackTrace()
}
}
当我 运行 directory.users().list().setCustomer(gIdToken.payload.subject).execute()
时,出现以下错误:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized
{
"code" : 401,
"errors" : [ {
"domain" : "global",
"location" : "Authorization",
"locationType" : "header",
"message" : "Invalid Credentials",
"reason" : "authError"
} ],
"message" : "Invalid Credentials"
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:146)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.interceptResponse(AbstractGoogleClientRequest.java:321)
我正在使用以下 Google 库:
<dependency>
<groupId>google-api-services</groupId>
<artifactId>admin-directory_v1</artifactId>
<version>1.22.0</version>
</dependency>
<dependency>
<groupId>com.google.gdata</groupId>
<artifactId>core</artifactId>
<version>1.47.1</version>
</dependency>
如何解决上述错误?
更新 2(2017 年 8 月 29 日 11:39 MSK): 尝试使用通讯录 API
尝试 1:联系人 API 供稿
import com.google.gdata.data.extensions.ContactFeed
fun readUsers2(gIdToken:GoogleIdToken, httpTransport: HttpTransport, jsonFactory:JsonFactory) {
val credential = GoogleCredential().setAccessToken(gIdToken.payload.accessTokenHash)
val service = ContactsService("Google Auth Test")
service.setOAuth2Credentials(credential)
val feedUrl = URL("https://www.googleapis.com/auth/contacts.readonly")
val resultFeed: ContactFeed = service.getFeed(feedUrl, ContactFeed::class.java)
}
结果:异常 "Unrecognized content type: text/plain"
com.google.gdata.client.Service#parseResponseData(com.google.gdata.data.ParseSource, com.google.gdata.wireformats.input.InputProperties, java.lang.Class<E>)
, 见
下面抛出语句。
private <E> E parseResponseData(ParseSource source, InputProperties inputProperties, Class<E> resultType) throws IOException, ServiceException {
Preconditions.checkNotNull("resultType", resultType);
AltFormat inputFormat = null;
String alt = inputProperties.getQueryParameter("alt");
if (alt != null) {
inputFormat = this.altRegistry.lookupName(alt);
}
if (inputFormat == null) {
inputFormat = this.altRegistry.lookupType(inputProperties.getContentType());
if (inputFormat == null) {
throw new ParseException("Unrecognized content type:" + inputProperties.getContentType());
}
}
尝试 2:联系人 API 查询
fun readUsers3(gIdToken:GoogleIdToken, httpTransport: HttpTransport, jsonFactory:JsonFactory) {
val credential = GoogleCredential().setAccessToken(gIdToken.payload.accessTokenHash)
val service = ContactsService("Google Auth Test")
service.setOAuth2Credentials(credential)
val feedUrl = URL("https://www.googleapis.com/auth/contacts.readonly")
val query = Query(feedUrl)
val resultFeed = service.query(query, ContactFeed::class.java)
}
结果:与尝试 2 中的异常相同。
更新 3(2017 年 8 月 29 日 13:04 MSK):
我尝试使用 API Explorer.
获取用户列表我收到 403
错误。详情如下。
要求:
GET https://www.googleapis.com/admin/directory/v1/users?domain={MYDOMAIN}&fields=users(emails%2Cid%2Cname)&key={YOUR_API_KEY}
回复:
403
- Show headers -
{
"error": {
"errors": [
{
"domain": "global",
"reason": "forbidden",
"message": "Not Authorized to access this resource/api"
}
],
"code": 403,
"message": "Not Authorized to access this resource/api"
}
}
更新 4(30.08.2017 13:19 MSK):
最后,我设法摆脱了身份验证和授权错误(在 测试安装 G 套件应用程序)。
但是,现在以下调用 return 一个空的用户列表(没有错误)。
val directory = Directory.Builder(
NetHttpTransport(),
JacksonFactory.getDefaultInstance(),
credential)
.setApplicationName("Google Auth Test")
.build()
val users = directory.users().list()
检查此 documentation to retrieve all users in the same domain, use the following GET
request and include the authorization described in Authorize requests。为了便于阅读,此示例使用行 returns:
GET https://www.googleapis.com/admin/directory/v1/users
?domain=primary domain name&pageToken=token for next results page
&maxResults=max number of results per page
&orderBy=email, givenName, or familyName
&sortOrder=ascending or descending
&query=email, givenName, or familyName:the query's value*
对于请求和响应属性,您可能需要使用 Users: list method wherein it retrieves a paginated list of either deleted users or all users in a domain. This request requires authorization with at least one of the following scopes (read more about authentication and authorization).
https://www.googleapis.com/auth/admin.directory.user.readonly
https://www.googleapis.com/auth/admin.directory.user
您需要从用户那里获得足够的权限才能获取域中所有用户的列表。此外,它只有在登录用户是域的超级管理员时才有效。
您可以获得权限列表here。
此问题与Google API/get directory contacts
相关我在这里发布一个答案,因为这个答案更 google 友好:
管理员目录 Users:list 资源允许在没有管理员权限的情况下列出公司目录。
只需确保将 viewType
设置为 domain_public
即可:
https://www.googleapis.com/admin/directory/v1/users?customer=my_customer&viewType=domain_public
https://www.googleapis.com/auth/admin.directory.user.readonly
的范围应该足够了。