Jump to content
Sign in to follow this  
Dave Craggs

MSGraph and OAuth

Recommended Posts

Hi,

 

I am struggling connecting to MSGraph and getting a working token back.

 

image.thumb.png.6717188d44c3680b3b919743e8705949.png

 

If I put this in I do not get a code back. If I change it to token I get a token, but that does not give me access to MSGraph.

 

I get ME - {"error":{"code":"InvalidAuthenticationToken","message":"Access token validation failure. Invalid audience.",

 

I was thinking maybe a need to get a code first and then ask for the token.

 

I am setting the scope to : https://graph.microsoft.com/.default

 

Anyone done this?

 

I have looked at GMailAuthDemo. https://github.com/geoffsmith82/GmailAuthSMTP/blob/master/GMailAuthDemo.dproj

 

Anyone done this?

 

Dave Craggs

Share this post


Link to post
Posted (edited)

Found a description of "Invalid audience"-here
https://stackoverflow.com/questions/75228773/access-token-validation-failure-invalid-audience-office-365-graph-api

Spelunked and found this, but haven't tried it myself
https://github.com/jfbilodeau/AzureRESTExample

 

There also is this thread, but I am uncertain if it came to conclusion?

 

OAuth2 isn't really a standard, but a guideline, and there can be fickle differences between implementations.

I successfully do OAuth2 authentication to our ERP systems, using System.Net.HTTPClient THTTPClient, and simulating a form post.
I couldn't get the REST OAuth component to work.

 

In the source below, TRes is a TObject containing the properties of the expected response body from the authentication - which should contain your tokens.

 

function TIONAPI.BuildStringStream(const NameValues: TNetHeaders): TStringStream;
var
  Encoded, Sep : string;
begin
  Sep := '';
  Encoded := '';
  for var item in NameValues
  do begin
    Encoded := Encoded + Sep + Item.Name + '=' + Encoder.EncodeForm(Item.Value);
    Sep := '&';
  end;
  Result := TStringStream.Create(UTF8String(Encoded));
end;

function TIONAPI.PostForm<TRes>(const aURL: string; const aFormFields: TNetHeaders; aExpectsResult: Boolean): TRes;
var
  HTTPRequest: IHttpRequest;
  HttpResponse: IHttpResponse;
  ReqBody: TStringStream;
  ResStatus: Integer;
  ResContent: string;
  ReqHeaders: TNetHeaders;
  T: TStopWatch;
begin
  Result := nil;
  ResStatus := 0;
  ReqBody := nil;
  FLastStatus := 0;
  FLastErrorMsg := '';

  try
    try
      DebugOut(Format('HTTP %s %s', ['POST', aURL])); // DO NOT TRANSLATE
      try
        HTTPRequest := HTTP.GetRequest('POST', aURL);
        HTTPRequest.RemoveHeader('User-Agent');

        HTTPRequest.SetCredential(IONCredentials.ResourceOwnerClientId, IONCredentials.ResourceOwnerClientSecret);

        ReqBody := BuildStringStream(aFormFields);
        HttpRequest.SourceStream := ReqBody;

        ReqHeaders := [
          TNetHeader.Create('content-type', mime.ApplicationXwwwForm),        // DO NOT TRANSLATE
          TNetHeader.Create('Expect', '100-continue')                         // DO NOT TRANSLATE
//          TNetHeader.Create('User-Agent', UserAgent);             // DO NOT TRANSLATE
        ];

        HTTP.PreemptiveAuthentication := True;

        T := TStopWatch.StartNew;
        HttpResponse := HTTP.Execute(HTTPRequest, nil, ReqHeaders);
        T.Stop;
        DebugOut('Status: ' + ResStatus.ToString + ' in ' + T.ElapsedMilliseconds.ToString+ ' ms');

        if Assigned(HttpResponse)
        then begin
          ResStatus := HttpResponse.StatusCode;
          ResContent := HttpResponse.ContentAsString(TEncoding.UTF8);
          if (ResStatus = 200)
          then begin
            try
              T := TStopWatch.StartNew;
              Result := TJson.JsonToObject<TRes>(ResContent);
            except
              on E: Exception
              do begin
                DebugOutException(E,
                  Format('TIONAPI.PostForm.%s<%s, %s> returned StatusCode: %d - but failed during conversion of "%s"', // DO NOT TRANSLATE
                  [aURL, '', Result.ClassName, ResStatus, ResContent]));
                ResStatus := HTTPStatus.ExpectationFailed417;
                Result := nil;
                FLastErrorMsg := E.Message;
              end;
            end;
          end
          else begin
            Result := nil;
          end;
        end
        else begin
          ResStatus := HTTPStatus.NoResponse;
          ResContent := '';
          Result := nil;
        end;

      except // Json Exception
        on E:Exception
        do begin
          DebugOutException(E);
          ResStatus := HTTPStatus.ExpectationFailed417;
        end;
      end;

    finally
//      DebugOut('Status: ' + ResStatus.ToString);
      ReqBody.Free;
    end;
  except // HTTP Exception
    on E: Exception
    do begin
      FLastStatus := ResStatus;
      FLastErrorMsg := E.Message;
      DebugOutException(E, Self.ClassName + '.PostForm'); // DO NOT TRANSLATE
    end;
  end;
end;

 

Edited by Lars Fosdal
Fixed an incomplete sentence

Share this post


Link to post

Thanks for the reply.

 

Have looked at some of those links already.

 

I think the issue is I am not getting the AuthCode

Share this post


Link to post

The issue I am having is getting back a token with the wrong aud.

 

Getting one fop Azure AD Graph (00000002-0000-0000-c000-000000000000) rather than Microsoft Graph.(00000003-0000-0000-c000-000000000000)

 

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×