为啥我使用 Azure Graph SDK 收到 400 Bad Request?
Posted
技术标签:
【中文标题】为啥我使用 Azure Graph SDK 收到 400 Bad Request?【英文标题】:Why I'm getting 400 Bad Request with Azure Graph SDK?为什么我使用 Azure Graph SDK 收到 400 Bad Request? 【发布时间】:2022-01-11 20:56:59 【问题描述】:我正在尝试使用 Microsoft Graph SDK 验证 Azure Active Directory 中是否存在用户电子邮件,但我收到 400 Bad Request。这是尝试执行此操作的 Java/Spring 中的代码。此代码实际上是从 Microsoft 网站的 Azure 文档中提取的:
@RequestMapping( value="/hello/email", method= RequestMethod.GET )
public ResponseEntity<User> holaMundo(@PathVariable("email") String email)
List<String> scopes = new ArrayList<String>();
scopes.add(".default");
String clientId = "5XXXXXX-XXXX-XXXX-XXXX-XXXX1d9c7c0";
String clientSecret = "GXXXX~zDXXXX~N6XXXXau7mXXXXEIDmaiWXr";
String tenantId = "39XXXX31-XXXX-XXXX-XXXX-14fXXXX4db8f";
final ClientSecretCredential clientSecretCredential = new ClientSecretCredentialBuilder()
.clientId(clientId)
.clientSecret(clientSecret)
.tenantId(tenantId)
.build();
final TokenCredentialAuthProvider tokenCredentialAuthProvider =
new TokenCredentialAuthProvider(scopes, clientSecretCredential);
final GraphServiceClient graphClient =
GraphServiceClient
.builder()
.authenticationProvider(tokenCredentialAuthProvider)
.buildClient();
User resultUser = null;
try
UserCollectionRequest ucr = graphClient.users().buildRequest().filter(email);
UserCollectionPage ucp = ucr.get(); // Here is the error
List<User> result = ucp.getCurrentPage();
User u = result.get(0);
return new ResponseEntity<>(resultUser, HttpStatus.OK);
catch (IndexOutOfBoundsException e)
return new ResponseEntity<>(null, HttpStatus.OK);
在 UserCollectionRequest 处引发错误或异常:
UserCollectionPage ucp = ucr.get(); // Here is the error
这是错误的输出:
2021-12-06 11:51:51.626 INFO 16828 --- [onPool-worker-1] c.azure.identity.ClientSecretCredential : Azure Identity => getToken() result for scopes [.default]: SUCCESS
2021-12-06 11:51:54.287 ERROR 16828 --- [nio-8080-exec-2] global : CoreHttpProvider[sendRequestInternal] - 406Graph service exception Error code: BadRequest
2021-12-06 11:51:54.288 ERROR 16828 --- [nio-8080-exec-2] global : CoreHttpProvider[sendRequestInternal] - 406Error message: Invalid filter clause
2021-12-06 11:51:54.288 ERROR 16828 --- [nio-8080-exec-2] global : CoreHttpProvider[sendRequestInternal] - 406
2021-12-06 11:51:54.288 ERROR 16828 --- [nio-8080-exec-2] global : CoreHttpProvider[sendRequestInternal] - 406GET https://graph.microsoft.com/v1.0/users?%24filter=fernando.rivas%40avianca.com
2021-12-06 11:51:54.289 ERROR 16828 --- [nio-8080-exec-2] global : CoreHttpProvider[sendRequestInternal] - 406SdkVersion : graph-java/v5.8.0
2021-12-06 11:51:54.289 ERROR 16828 --- [nio-8080-exec-2] global : CoreHttpProvider[sendRequestInternal] - 406
2021-12-06 11:51:54.289 ERROR 16828 --- [nio-8080-exec-2] global : CoreHttpProvider[sendRequestInternal] - 406
2021-12-06 11:51:54.289 ERROR 16828 --- [nio-8080-exec-2] global : CoreHttpProvider[sendRequestInternal] - 406400 : Bad Request
2021-12-06 11:51:54.290 ERROR 16828 --- [nio-8080-exec-2] global : CoreHttpProvider[sendRequestInternal] - 406[...]
2021-12-06 11:51:54.290 ERROR 16828 --- [nio-8080-exec-2] global : CoreHttpProvider[sendRequestInternal] - 406
2021-12-06 11:51:54.290 ERROR 16828 --- [nio-8080-exec-2] global : CoreHttpProvider[sendRequestInternal] - 406[Some information was truncated for brevity, enable debug logging for more details]
2021-12-06 11:51:54.290 ERROR 16828 --- [nio-8080-exec-2] global : Throwable detail: com.microsoft.graph.http.GraphServiceException: Error code: BadRequest
Error message: Invalid filter clause
GET https://graph.microsoft.com/v1.0/users?%24filter=fernando.rivas%40avianca.com
SdkVersion : graph-java/v5.8.0
400 : Bad Request
[...]
[Some information was truncated for brevity, enable debug logging for more details]
2021-12-06 11:51:54.297 ERROR 16828 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is com.microsoft.graph.http.GraphServiceException: Error code: BadRequest
Error message: Invalid filter clause
GET https://graph.microsoft.com/v1.0/users?%24filter=fernando.rivas%40avianca.com
SdkVersion : graph-java/v5.8.0
400 : Bad Request
[...]
[Some information was truncated for brevity, enable debug logging for more details]] with root cause
com.microsoft.graph.http.GraphServiceException: Error code: BadRequest
Error message: Invalid filter clause
GET https://graph.microsoft.com/v1.0/users?%24filter=fernando.rivas%40avianca.com
SdkVersion : graph-java/v5.8.0
400 : Bad Request
[...]
[Some information was truncated for brevity, enable debug logging for more details]
at com.microsoft.graph.http.GraphServiceException.createFromResponse(GraphServiceException.java:419) ~[microsoft-graph-core-2.0.10.jar:na]
at com.microsoft.graph.http.GraphServiceException.createFromResponse(GraphServiceException.java:378) ~[microsoft-graph-core-2.0.10.jar:na]
at com.microsoft.graph.http.CoreHttpProvider.handleErrorResponse(CoreHttpProvider.java:511) ~[microsoft-graph-core-2.0.10.jar:na]
at com.microsoft.graph.http.CoreHttpProvider.processResponse(CoreHttpProvider.java:440) ~[microsoft-graph-core-2.0.10.jar:na]
at com.microsoft.graph.http.CoreHttpProvider.sendRequestInternal(CoreHttpProvider.java:406) ~[microsoft-graph-core-2.0.10.jar:na]
at com.microsoft.graph.http.CoreHttpProvider.send(CoreHttpProvider.java:223) ~[microsoft-graph-core-2.0.10.jar:na]
at com.microsoft.graph.http.CoreHttpProvider.send(CoreHttpProvider.java:200) ~[microsoft-graph-core-2.0.10.jar:na]
at com.microsoft.graph.http.BaseCollectionRequest.send(BaseCollectionRequest.java:102) ~[microsoft-graph-core-2.0.10.jar:na]
at com.microsoft.graph.http.BaseEntityCollectionRequest.get(BaseEntityCollectionRequest.java:78) ~[microsoft-graph-core-2.0.10.jar:na]
at com.pbi336328.adverifyuser.Pbi336328.holaMundo(Pbi336328.java:56) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_301]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_301]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_301]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_301]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197) ~[spring-web-5.3.8.jar:5.3.8]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141) ~[spring-web-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1063) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.8.jar:5.3.8]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) ~[tomcat-embed-core-9.0.48.jar:4.0.FR]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.8.jar:5.3.8]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.48.jar:4.0.FR]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:228) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.48.jar:9.0.48]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.8.jar:5.3.8]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.8.jar:5.3.8]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.8.jar:5.3.8]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.8.jar:5.3.8]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.8.jar:5.3.8]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.8.jar:5.3.8]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1723) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.48.jar:9.0.48]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_301]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_301]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.48.jar:9.0.48]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_301]
【问题讨论】:
看起来您给过滤器的方式是问题,您可能需要传递过滤器字符串,例如 email='your-email-here',否则 API 不知道您通过哪个属性过滤或搜索。请参阅此 question 尝试按显示名称搜索。 而当你使用过滤器,搜索参数,那么额外的HTTP头ConsistencyLevel
=最终必须设置,见doc
【参考方案1】:
看起来您提供过滤器的方式导致错误,您可能需要传递过滤器字符串,例如 email='your-email-here' 或 request option
,否则 API 不知道您使用哪个属性正在过滤或搜索。请参阅此question,它尝试通过用户的display name
进行搜索,并且还使用了request option
。
而且,当您使用 sdk 查询 MS Graph API 时,在应用 $filter、$search 时,您必须设置额外的 HTTP 标头 ConsistencyLevel = eventual
并传递 $count
,按照 official doc 和 @987654323 中的此页面@
【讨论】:
您现在对过滤器有理由,但现在我收到了一个禁止错误以上是关于为啥我使用 Azure Graph SDK 收到 400 Bad Request?的主要内容,如果未能解决你的问题,请参考以下文章