Jump to content

Officeapi

Members
  • Content Count

    19
  • Joined

  • Last visited

Community Reputation

1 Neutral
  1. It turns out that TRESTResponse may have some bug. Remember the 'ContentLength' is 348, and 'Content' is empty? After encode the 'RawBytes' of the response, I can see the profile content. For some unknown reason, TRESTResponse ignores the content. Thanks for all the replies.
  2. I created TRESTClient/Request in the code, and used seperate Clients. Still got JSONValue null. Is it possible that TRESTClient doesn't work in some situation?
  3. I don't have setting 'Accept'. After I added req.AddParameter('Accept', ctAPPLICATION_JSON, pkHTTPHEADER, [TRESTRequestParameterOption.poDoNotEncode]); the JSONValue is still null. Just check the component, there is setting for Accept: 'application/json, text/plain; q=0.9, text/html;q=0.8,'
  4. Here are the values I got during debug: RESTProfileResponse.Content : '' RESTProfileResponse.ContentLength : 348 RESTProfileResponse.ContentType : 'application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false' RESTProfileResponse.ContentEncoding : '' RESTProfileResponse.FullRequestURI : 'https://graph.microsoft.com/v1.0/me' RESTProfileResponse.Headers : (nil, $5A528A0, #$D#$A, nil, 0, ',', '"', '=', [soWriteBOM,soTrailingLineBreak,soUseLocale]) RESTProfileResponse.JSONText : '' RESTProfileResponse.JSONValue : nil RESTProfileResponse.Observers : ($120E3090, TComponent.GetObservers$ActRec($120FFAB4) as TObservers.TCanObserveEvent, TComponent.GetObservers$ActRec($120FFAB0) as TObservers.TObserverAddedEvent) RESTProfileResponse.RootElement : '' RESTProfileResponse.StatusCode : 200
  5. I used Charles Proxy to check the request/response for the GraphAPI call from my code (/v1.0/me), and it actually got my profile. But in the Delphi code, the he JSONValue of the response is nil. Here is the code to get the response: FieldRawResponse.Text := TJSON.Format(RESTListResGroupResponse.JSONValue); I also check that RESTListResGroupResponse.content is empty too. Here is the info I get from Charles Proxy
  6. Thanks for the reply. After I used seperate TRESTClient for Graph api call, I don't have 401 error anymore. Now the response has StatusCode 200. However, the JSONValue of the response is nil. I only want to get login user profile (https://graph.microsoft.com/v1.0/me), and the delegated permissions are in my first post. The scope for Access Token is: RESTTokenRequest.Params.AddItem('scope', 'IMAP.AccessAsUser.All Mail.Read Mail.ReadWrite Mail.Send offline_access openid POP.AccessAsUser.All profile User.Read Mail.Read', TRestRequestParameterKind.pkREQUESTBODY); I believe 'User.Read' is the only permission actually needed. What we have are more than enough. When I used the same token in Postman, I can get my profile. The response is also in my first post.
  7. Thanks for the update. I tried with RestClient.AddAuthParameter, now the error became 'HTTP1.1 400 Bad Request'.
  8. I switched the 'Clear' and 'Resource' lines, and used 'AddParameter' as well. I saved the access token in 'FConnection.AuthToken'. Still the same result (401 unauthorized).
  9. I also tried to use Charles Proxy to check the request/response for Graph API (GET https://graph.microsoft.com/v1.0/me), I got the follow error in Charles Proxy window: { "error": { "code": "InvalidAuthenticationToken", "message": "CompactToken parsing failed with error code: 80049217", "innerError": { "date": "2023-11-06T19:13:00", "request-id": "65e9c9d2-68ca-4081-bcfa-63a7cc1a1fa4", "client-request-id": "65e9c9d2-68ca-4081-bcfa-63a7cc1a1fa4" } } } I also copied the access token, and used it in Postman, it still worked. I am using Delphi 11. What could be the problem?
  10. I have tried to mimic what Postman sent. But still got the same error. Here is my code RESTClient.BaseURL := FConnection.RESTEndPoint; // https://graph.microsoft.com RESTProfileRequest.Method := TRESTRequestMethod.rmGet; RESTProfileRequest.Resource := 'v1.0/me'; RESTProfileRequest.Params.Clear; RESTProfileRequest.Params.AddItem('Authorization', 'Bearer ' + FConnection.AuthToken, TRESTRequestParameterKind.pkHTTPHEADER, [poDoNotEncode]); RESTProfileRequest.Params.AddItem('Content-Type', 'application/json', TRESTRequestParameterKind.pkHTTPHEADER); RESTProfileRequest.Params.AddItem('User-Agent', 'PostmanRuntime/7.34.0', TRESTRequestParameterKind.pkHTTPHEADER); RESTProfileRequest.Params.AddItem('Accept', '*/*', TRESTRequestParameterKind.pkHTTPHEADER); // RESTProfileRequest.Params.AddItem('Postman-Token', 'e08693a1-7ca4-463f-b83f-bd3c7878c798', TRESTRequestParameterKind.pkHTTPHEADER); RESTProfileRequest.Params.AddItem('Host', 'graph.microsoft.com', TRESTRequestParameterKind.pkHTTPHEADER); RESTProfileRequest.Params.AddItem('Accept-Encoding', 'gzip, deflate, br', TRESTRequestParameterKind.pkHTTPHEADER); RESTProfileRequest.Params.AddItem('Connection', 'keep-alive', TRESTRequestParameterKind.pkHTTPHEADER); RESTProfileRequest.ExecuteAsync;
  11. Here is the code to call Graph api: RESTClient.BaseURL := FConnection.RESTEndPoint; // https://graph.microsoft.com RESTProfileRequest.Method := TRESTRequestMethod.rmGet; RESTProfileRequest.Resource := 'v1.0/me'; RESTProfileRequest.Params.Clear; RESTProfileRequest.Params.AddItem('Authorization', 'Bearer ' + FConnection.AuthToken, TRESTRequestParameterKind.pkHTTPHEADER, [poDoNotEncode]); RESTProfileRequest.Params.AddItem('Content-Type', 'application/json', TRESTRequestParameterKind.pkHTTPHEADER); RESTProfileRequest.ExecuteAsync; I am stuck here for several days. Any suggestion will be appreciated.
  12. I did check Microsoft Ignite on how to get user profile. What I need is a sign-in user getting his own profile, not the application type. If you check my first post, all permissions are delegated. Maybe my code used it wrong? It is a desktop application. I did get the access token. I copied the token to Postman, it worked with GET https://graph.microsoft.com/v1.0/me Here is how I get access token (for the scope, I just list all permissions in Entra setting, I believe the one actually needed is User.Read): RestClient.BaseURL := FConnection.TokenEndPoint; //'https://login.microsoftonline.com/' + FConnection.TenantId + '/oauth2/v2.0/token' RESTTokenRequest.Method := TRESTRequestMethod.rmPOST; RESTTokenRequest.Params.Clear; RESTTokenRequest.Params.AddItem('tenant', FConnection.TenantId, TRestRequestParameterKind.pkQUERY); RESTTokenRequest.Params.AddItem('client_id', FConnection.ClientId, TRestRequestParameterKind.pkQUERY); RESTTokenRequest.Params.AddItem('grant_type', 'authorization_code', TRestRequestParameterKind.pkREQUESTBODY); RESTTokenRequest.Params.AddItem('client_id', FConnection.ClientId, TRestRequestParameterKind.pkREQUESTBODY); RESTTokenRequest.Params.AddItem('code', FConnection.AuthCode, TRestRequestParameterKind.pkREQUESTBODY); RESTTokenRequest.Params.AddItem('scope', 'IMAP.AccessAsUser.All Mail.Read Mail.ReadWrite Mail.Send offline_access openid POP.AccessAsUser.All profile User.Read Mail.Read', TRestRequestParameterKind.pkREQUESTBODY); RESTTokenRequest.Params.AddItem('redirect_uri', FConnection.RedirectURL, TRestRequestParameterKind.pkREQUESTBODY); //'https://login.microsoftonline.com/common/oauth2/nativeclient' RESTTokenRequest.Params.AddItem('response_type', 'code', TRestRequestParameterKind.pkREQUESTBODY); RESTTokenRequest.ExecuteAsync;
×