XeroAPI / Xero-NetStandard

A wrapper of the Xero API in the .NetStandard 2.0 framework. Supports Accounting, Payroll AU/US, and Files
MIT License
127 stars 124 forks source link

Invalid_grant error #441

Closed danielmyrtle closed 2 years ago

danielmyrtle commented 2 years ago

SDK you're using (please complete the following information): Xero.NetStandard.OAuth2Client 1.3.1

Describe the bug As of the 14th of September our integration with Xero has stopped working across all of our platforms. We have confirmed this is not related to any release we have done or changes we have made to our platform. We have also restored older versions of our platform where Xero was proven to work and these issues still persist.

We require support to understand what has changed around this date that would cause our issue below. I have been in touch with the Xero App support team and they have asked me to reach out here for further assistance. We have been trying to get to the root cause of this for 2 days now and really just need a clear steer on what we need to do to resolve this issue.

When we attempt to get the tokens we attempt to access https://identity.xero.com/connect/token with this body (example taken from our development environment, though is occurring across all environments): { "grant_type": "authorization_code", "code": "ihjfddvdlq3ehuhfxrfqxh2w3oujf7o7mf5h7lk5-_q", "redirect_uri": "[/SPACECONTROL/App/505/Xero%20Export] (SPACECONTROL/App/505/Xero%20Export)", "code_verifier": null, "scope": "openid profile email files accounting.transactions accounting.transactions.read accounting.reports.read accounting.journals.read accounting.settings accounting.settings.read accounting.contacts accounting.contacts.read accounting.attachments accounting.attachments.read offline_access" } This returns a 400 bad request response with content: {"error":"invalid_grant"}

Expected behavior We should be able to access the refresh token and allow authentication

Any more information required, let me know. There should also be a lot of history in our case open with your app support team.

RettBehrens commented 2 years ago

Hi @danielmyrtle what version of Xero.NetStandard.OAuth2 are you running? Current version is 3.28.0

Xero.NetStandard.OAuth2Client 1.3.1 is outdated, current version is 1.6.0.

I have tried to replicate the described issue with our sample app running the current versions and have not been able to reproduce the error.

danielmyrtle commented 2 years ago

Thanks for your prompt response @RettBehrens

Was something disabled this week that has now stopped 1.3.1 from being a valid version? What would now cause our requests to begin to fail within the last week? Would it be possible to revert that while we work further on a solution?

Our dev team did notice the version difference and attempted an upgrade to 1.6.0 today. They still continued to get the error described above. What would be your next suggestion after upgrading to 1.6.0 to continue to investigate this issue?

RettBehrens commented 2 years ago

Are you running Xero.NetStandard.OAuth2 version 3.28.0 as well?

Nothing that we intentionally disabled.

Is this affecting all orgs or a select few?

We did update RestSharp dependency in the latest release to address community requests. In their issues, they were using a newer version elsewhere in their projects and our SDK was using an outdated version.

We tested the SDK in our sample app with no issues after the update, but I'm wondering if you might be experiencing the issue in reverse - newer version in SDK than somewhere else in your project?

RettBehrens commented 2 years ago

Hey @danielmyrtle wanted to follow up on this after the weekend - are you still having issues?

danielmyrtle commented 2 years ago

Hi @RettBehrens ,

Thanks for following up and the quick responses, we have been reviewing this with our development team.

We have updated to OAuth2Client to 1.6.0 and are experiencing the same issue and also validated that RestSharp in our project is the same version across the board.

We aren't using Xero.Netstandard.Oauth2 in our project. Is it necessary to implement this in order to get our integration running again?

RettBehrens commented 2 years ago

@danielmyrtle thank you for further info.

We have not made changes to Xero.NetStandard.OAuth2Client since 1.6.0 was released in May. Xero.NetStandard.OAuth2Client also does not list RestSharp as a dependency.

You do not need to use Xero.NetStandard.OAuth2 to get your integration running again.

Unfortunately, given the latest information, I do not believe this to be an issue caused by the SDK because you began experiencing issues on September 14th while only using Xero.NetStandard.OAuth2Client 1.3.1 - released and unchanged since April 2021. Since you do not use the package released September 12th, it seems the timing is coincidence.

I have a couple remaining troubleshooting ideas:

  1. From the the sample body above you are using "grant_type": "authorization_code" but also sending "code_verifier": null - a property needed for PKCE auth flow. Can you try removing the code_verifier property before sending?
  2. Between your sample body and the described expected behavior it seems your referring to three different steps of the oauth2 code flow - can you double check your integration follows these steps?
  3. I can see that you've reached maximum connection limit for an uncertified app. I've increased this limit for troubleshooting purposes - any change to behavior?
  4. Can you test using Insomnia or Postman?
danielmyrtle commented 2 years ago

@RettBehrens

Thank you for your troubleshooting ideas. We have confirmed the connection limit has not helped resolved the issue, we are still getting the invalid grant error. We have also removed the code verifier value and still continue to get invalid grant.

2 and 4 we are currently working on and will update you as soon as we have completed this.

danielmyrtle commented 2 years ago

@RettBehrens

re 2 We are receiving HTTP 400 {"error":"invalid_grant"} response from "3. Exchange the code" step. Manually we were able to get that step working i.e. receive tokens. We have noticed that we get the "invalid_grant" response if we use same "code" parameter more than once. Is that the expected behaviour? If so would it be possible to confirm from your side if our apps are sending the same request in step 3 more than once?

re 4 we verified the above using Postman

RettBehrens commented 2 years ago

@danielmyrtle per the docs:

code: a temporary code that may only be exchanged once and expires 5 minutes after issuance.

I have not found duplicate calls but can't rule it out at this time. Can you check your logs to see if you sent this auth code more than once? lznai8ghjkkju8ux56j_26cfrhyzo6enbveyimrgyws This auth code resulted in a 400 / invalid_grant / invalid_authorization_code

danielmyrtle commented 2 years ago

@RettBehrens

We believe he have found the issue. In our code we convert the code to lowercase always. Looks like that used to work up to a point but not anymore. From now on we will make sure to handle the code in case-sensitive way.

We would still like to confirm if there was a change on your side in code validation. Seems that until recently you were verifying the code in case-insensitive way. Now it looks like case-sensitive comparison on your side. Could you confirm that for us?

RettBehrens commented 2 years ago

Thanks @danielmyrtle. I'll share this with the API-CX team and let you know what I hear. At this point I'm confident this wasn't introduced via an SDK update. Just holding off on closing the issue until I hear from API-CX

RettBehrens commented 2 years ago

@danielmyrtle I've heard back:

"I can confirm that on the 14th September we deployed an update to Identity which consumes a slightly newer version of the underlying IdentityServer4 library that helps perform our OIDC / OAuth2 implementation. Looks like something in that upgrade tweaked how Authorization Code generation and validation worked. The library changes haven’t really touched the part of the code which validates Authorization Codes - for all intents and purpose it should have been case sensitive already. Additionally, clients should not be making any changes to the Authorization Code before sending it to us to exchange for an access token."

Closing this issue as we've confirmed it was not caused by the SDK.

danielmyrtle commented 2 years ago

@RettBehrens Thank you for confirming!

Is there a channel or something we can subscribe to where we can see future updates? Do you offer a UAT environment that we can test the changes before they are released to production?

Just looking for a way to help mitigate this in the future.