如何通过Azure AD Java SDK获取用户默认属性及onPremisesSamAccountName
问题:使用Azure AD SDK Java获取用户时同时包含默认属性与onPremisesSamAccountName
现有获取所有用户的代码
List<User> users = new ArrayList<>(); try { UserCollectionRequestBuilder usersClientBuilder = graphClient.users(); UserCollectionRequest usersRequest = usersClientBuilder.buildRequest(); do { UserCollectionPage userCollectionPage = usersRequest.get(); users.addAll(userCollectionPage.getCurrentPage()); usersClientBuilder = userCollectionPage.getNextPage(); if (usersClientBuilder == null) { usersRequest = null; } else { usersRequest = usersClientBuilder.buildRequest(); } } while (usersRequest != null); } catch (GraphServiceException e) { log.error("GraphServiceException occurred in getAllUsers() : ", e); }
当前返回的用户属性
{ "businessPhones": [], "displayName": "avinash#kumar2", "givenName": "Avinash", "jobTitle": null, "mail": "avinash@test.com", "mobilePhone": null, "officeLocation": null, "preferredLanguage": null, "surname": "Kumar2", "userPrincipalName": "avinash#kumar2@testshare.onmicrosoft.com", "id": "217ae76c-585b-44be-864a-e33a764ff199" }
需求
需要在上述默认返回属性的基础上,额外获取onPremisesSamAccountName属性。
错误尝试代码
List<User> users = new ArrayList<>(); try { List<Option> requestOptions = new ArrayList<Option>(); requestOptions.add(new QueryOption("$select", "'=onPremisesSamAccountName'")); requestOptions.add(new QueryOption("$count", "true")); requestOptions.add(new HeaderOption("ConsistencyLevel", "eventual")); Instant start = Instant.now(); UserCollectionRequestBuilder usersClientBuilder = graphClient.users(); UserCollectionRequest usersRequest = usersClientBuilder.buildRequest(requestOptions); do { UserCollectionPage userCollectionPage = usersRequest.get(); users.addAll(userCollectionPage.getCurrentPage()); usersClientBuilder = userCollectionPage.getNextPage(); if (usersClientBuilder == null) { usersRequest = null; } else { usersRequest = usersClientBuilder.buildRequest(); } } while (usersRequest != null); } catch (GraphServiceException e) { log.error("GraphServiceException occurred in getAllUsers() : ", e); }
错误信息
SEVERE: CoreHttpProvider[sendRequestInternal] - 408Graph service exception Mar 19, 2024 6:57:51 PM com.microsoft.graph.logger.DefaultLogger logError SEVERE: Throwable detail: com.microsoft.graph.http.GraphServiceException: Error code: BadRequest Error message: Parsing OData Select and Expand failed: An identifier was expected at position 0. GET https://graph.microsoft.com/v1.0/users?%24select=%3DonPremisesSamAccountName SdkVersion : graph-java/v5.53.0 400 : [...] [Some information was truncated for brevity, enable debug logging for more details]
解决方案
错误原因
$select参数格式错误:不需要多余的'=符号,直接指定属性名即可。- 使用
$select后,Graph API只会返回指定的属性,因此需要显式列出所有默认属性,再加上onPremisesSamAccountName才能同时获取两者。 - 分页请求时未传递
requestOptions,导致下一页请求不会携带$select参数。
修正后的代码
List<User> users = new ArrayList<>(); try { // 定义需要返回的所有属性:默认属性 + onPremisesSamAccountName String selectProperties = "businessPhones,displayName,givenName,jobTitle,mail,mobilePhone,officeLocation,preferredLanguage,surname,userPrincipalName,id,onPremisesSamAccountName"; List<Option> requestOptions = new ArrayList<>(); requestOptions.add(new QueryOption("$select", selectProperties)); // 若不需要$count和ConsistencyLevel可删除以下两行 requestOptions.add(new QueryOption("$count", "true")); requestOptions.add(new HeaderOption("ConsistencyLevel", "eventual")); UserCollectionRequestBuilder usersClientBuilder = graphClient.users(); UserCollectionRequest usersRequest = usersClientBuilder.buildRequest(requestOptions); do { UserCollectionPage userCollectionPage = usersRequest.get(); users.addAll(userCollectionPage.getCurrentPage()); usersClientBuilder = userCollectionPage.getNextPage(); if (usersClientBuilder != null) { // 分页请求时必须传递requestOptions,确保下一页也携带$select参数 usersRequest = usersClientBuilder.buildRequest(requestOptions); } else { usersRequest = null; } } while (usersRequest != null); } catch (GraphServiceException e) { log.error("GraphServiceException occurred in getAllUsers() : ", e); }
说明
- 显式列出所有默认属性,确保返回结果包含原有的所有字段,同时新增
onPremisesSamAccountName。 - 分页时必须将
requestOptions传递给buildRequest方法,保证每一页请求都应用相同的$select参数。 - 若不需要获取用户总数(
$count),可删除对应的QueryOption和HeaderOption,简化请求。
内容的提问来源于stack exchange,提问作者Avinash Reddy
相关产品推荐
相关产品推荐

