AppAuth-Android icon indicating copy to clipboard operation
AppAuth-Android copied to clipboard

Response state param did not match request state

Open kevinlee-app opened this issue 2 years ago • 14 comments

Configuration

  • Version: 0.11.1
  • Integration: native(Java)
  • Identity provider: Auth0

Description

Recently we tried to update the AppAuth-Android version used on our project from version 0.5.1.5 to 0.11.1. When successfully login from the browser and come back to the app, there is error data and we can't continue the process.

This is how we request:

AuthorizationServiceConfiguration configuration = new AuthorizationServiceConfiguration(Uri.parse(getAuthorizationRequestUrlWithParams(getBaseUrl(), getAuthorizationUrlParameters())), Uri.parse(getAccessTokenUrl()), null);

AuthorizationRequest.Builder authRequestBuilder = new AuthorizationRequest.Builder(
                    configuration,
                    mClientId,
                    "code token id_token",
                    Uri.parse(getCallbackURI()))
                    .setScope(getHybridScope());

Intent completionIntent = new Intent(context, tokenActivity);
Intent cancelIntent = getCancelIntent(context, cancelActivity);
CustomTabColorSchemeParams colorSchemeParams = new CustomTabColorSchemeParams.Builder()
                    .setToolbarColor(ContextCompat.getColor(context,R.color.grey120))
                    .setSecondaryToolbarColor(ContextCompat.getColor(context,R.color.black))
                    .build();

int flags = 0;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
    flags |= PendingIntent.FLAG_MUTABLE;
}

mAuthService.performAuthorizationRequest(
                    authRequestBuilder.build(),
                    PendingIntent.getActivity(context, 0, completionIntent, flags),
                    PendingIntent.getActivity(context, 0, cancelIntent, flags),
                    mAuthService.createCustomTabsIntentBuilder()
                            .setDefaultColorSchemeParams(colorSchemeParams)
                            .build());

On authorization completed, the responseData has error data with description Response state param did not match request state.

After some debugging, we found out that on AuthorizationResponse.java there is a builder function that failed to get the query parameters from Uri which result in null value although the Uri string already contains all the data.

We also tried to setResponseMode to "form_post" on authRequestBuilder when requesting but it looks like it's still not supported.

Does anyone happen to solved this before? Thanks in advance.

kevinlee-app avatar Jun 30 '22 06:06 kevinlee-app

I have the same issue. It seems to be happening on anndroid emulator consistently. @kevinlee-app did you find a solution?

kostadin-damyanov-prime avatar Aug 03 '22 09:08 kostadin-damyanov-prime

Facing the same error. Sometimes on real devices but every-time on android emulator. Any updates / suggestions here?

Cantinaband avatar Jan 25 '23 15:01 Cantinaband

I have a similar code as you put in the description. I receive a same error message, The Response state param did not match the request state, When I test my app on devices running with Android 9.0 and below. However, log in functionality goes well on Android 10 and above. I don't know if there is any restriction by the library!

HesamKamalan avatar Oct 23 '23 17:10 HesamKamalan

I think there is a bug in the library. You get this error when using the Implicit flow (response type token), where auth result is passed to the client not through query params (?) but through reference/fragment (#): my-app://oauth2redirect#state=Rve0AbxNWLEx6StF99Fg_Q&session_state=e40fe780-3942-4501-a254-... But the library always expects the response to be in query params and so fails to parse it: https://github.com/openid/AppAuth-Android/blob/c6137b7db306d9c097c0d5763f3fb944cd0122d2/library/java/net/openid/appauth/AuthorizationResponse.java#L225-L227

Radiokot avatar Oct 25 '23 12:10 Radiokot

I suggest using explicit flow (response type code) until it is fixed 🤷‍♂️

Radiokot avatar Oct 25 '23 12:10 Radiokot

@Radiokot Could you make an example of what this code would look like? I'm going through the same problem

wyllyamjesus-hotmart avatar Oct 25 '23 12:10 wyllyamjesus-hotmart

@wyllyamjesus-hotmart

  1. You set the response type of your authorization request to ResponseTypeValues.CODE
  2. Once you've received AuthorizationResponse in your activity, get the access token by authService.performTokenRequest(authResponse.createTokenExchangeRequest())

This is the flow described in the library readme: https://github.com/openid/AppAuth-Android/#implementing-the-authorization-code-flow

Radiokot avatar Oct 25 '23 12:10 Radiokot

@Radiokot

I have already implemented this flow, but it still has problems, from the logs I received in Firebase's crashlytics, the problem is occurring within the AuthorizationManagementActivity class, in the extractResponseData function (line 342). The flow enters the else and after that the problem occurs in the if as it does not include validation.

wyllyamjesus-hotmart avatar Oct 25 '23 12:10 wyllyamjesus-hotmart

@wyllyamjesus-hotmart then I think this is not the implicit flow issue, can't help you with that.

Radiokot avatar Oct 25 '23 13:10 Radiokot

I have a similar code as you put in the description. I receive a same error message, The Response state param did not match the request state, When I test my app on devices running with Android 9.0 and below. However, log in functionality goes well on Android 10 and above. I don't know if there is any restriction by the library!

I found something new. I could resolve my issue on a device with Android 9.0. It is something related to the Browser being used for authentication. As I am testing on Browserstack, whenever I launch a new device I get a fresh device. In this case, I am testing on Samsung S10 (Android 9). I get Response state param did not match request state error message as soon as I tap my Login button (Browser opens and closes instantly). Then I go to device settings/apps/Chrome and set it as my default browser. Then I launch my app and tap on the Login button. I can see the Login web page and complete the authentication.

So, I thought the issue was happening because I have AnyBrowserMatcher.INSTANCE in my AppAuthConfiguration. Then I changed it using the way mentioned here. I allow only CHROME_CUSTOM_TAB and SAMSUNG_CUSTOM_TAB. I launch a new device and install the app on a new device (on Browserstack). I launch the app and tap on the Login button. I still get the error message. I set Chrome as the default browser, launch the app and can see the login on the webpage. So, have no idea what these settings do. But at least we know the error is related to the picked browser.

HesamKamalan avatar Nov 09 '23 19:11 HesamKamalan

As @Radiokot said the reason this happens seems to be because the pararmeters are appended to the redirect url in a URI fragment instead of as query parameters if you set the response type to id_token instead of code which AuthorizationResponse.Builder::fromUri can't parse by using uri.getQueryParameter.

The reason why this differs between the implicit grant and the authorization code grant is explained in detail here: https://community.auth0.com/t/the-redirect-response-does-not-send-the-hash-fragment-tokens-to-the-server-side/6180/2

davidkarlsson avatar Dec 05 '23 11:12 davidkarlsson

I've also found that missing support for implicit grant flow is intentional. This flow is considered deprecated and unsafe (for good reasons), so the library maintainers do not want to implement it. However, this is confusing because there is the ResponseTypeValues.TOKEN constant available to use and not marked as deprecated or experimental. https://github.com/openid/AppAuth-Android/issues/221#issuecomment-298422560

Radiokot avatar Dec 05 '23 12:12 Radiokot

Just struggled with the same problem. It would be nice if ResponseTypeValues.TOKEN could be marked as deprecated.

svenjacobs avatar Dec 05 '23 14:12 svenjacobs