Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to get server-side authorization code ? #293

Closed
Timenote opened this issue Oct 31, 2017 · 10 comments
Closed

Is it possible to get server-side authorization code ? #293

Timenote opened this issue Oct 31, 2017 · 10 comments
Labels

Comments

@Timenote
Copy link

Hi, first of all thank you for this amazing work.

For 10 hours now i've been trying to generate an authorization code (on my Android App) to send to my server in order to get a refresh token (on my server) exactly like i've been doing on iOS (and previously on Android when i was using the official Android Google Sign-in SDK) simply by providing the client_id of my server. But now that i can't provide any serverClientId, i'm facing this error (server-side) everytime i try to exchange authorization code to refresh-token : "invalid_grant", "Missing code verifier."

And this is why i'm asking you guys a question : is it possible with this library to get an authorization code on my app that can be exchanged to refresh_token on my server ?

(I'm not using the official Google Sign in SDK because i can't choose between normal or brand account on YouTube).

Thanks !

@iainmcgin
Copy link
Member

It sounds like you're probably doing everything right, but that the default-on PKCE support in AppAuth is causing you issues. It should be sufficient to call setCodeVerifier(null) on the builder for your AuthorizationRequest, which will disable PKCE. This is fine, as you will be using a client secret to as proof of identity for the authorization code exchange.

@Timenote
Copy link
Author

Thank you for your response but now i have a new error :

array(2) {
["error"]=>
string(19) "unauthorized_client"
["error_description"]=>
string(12) "Unauthorized"
}

I want to precise that i get the authorization code directly on my Android App (with the client_id of my Android App), and try to get an access token with the id_client of my server (who is different).

@Timenote
Copy link
Author

Timenote commented Nov 1, 2017

Or maybe that's would be very helpful if you can help me understanding what the official Android Google Sign In SDK is doing more when we provide :

.requestServerAuthCode(serverClientId, false)

(https://developers.google.com/identity/sign-in/android/offline-access)

Thanks a lot iainmcgin 👍

@iainmcgin
Copy link
Member

If you are requesting an authorization code for exchange by your server, you should use the client ID that your server owns (typically a web client ID). This may cause further complications as your app will likely now need to be able to capture https redirects, which requires that you configure app links correctly, or you must have a redirect URL configured that would allow your backend to directly capture the authorization response.

AppAuth's primary use case is for authorizing your app rather than your backend. Other use cases (such as yours) can still be serviced using the library, but some deeper knowledge of OAuth2 is typically required. At some point I hope to write a book on all of these flows and how to implement them with AppAuth, but for now there is just some inherent complexity to OAuth2 in native apps that you'll have to learn about and deal with.

@iainmcgin
Copy link
Member

The Google SDK does some undocumented, non-standard things to simultaneously authorize your Android app and your backend. There's not really an equivalent in the OAuth2 or OpenID connect specs right now; it's essentially retrieving two authorization codes for two related client IDs at the same time.

Without a standard way to do this in OAuth2, the least awkward option for now is to authorize your native app and then share the refresh code with your backend. This has potential security implications, and I don't like recommending it, but there is little else that can be done in practice for now.

@Timenote
Copy link
Author

Timenote commented Nov 1, 2017

Okay ! So there is no easy way on Android to be able to login with a Google account and choose between brand or others account exactly like the Google Sign In for iOS ?

@IzabellaConigliaro
Copy link

@Timenote I'm facing the same issue. Did you solve it?

@iainmcgin
Copy link
Member

Closing this as I feel I sufficiently answered the question - there is no standard way to authorize two related clients simultaneously in OAuth2 / OIDC. In general, I would suggest authorizing your backend and then submitting all requests that require authorization from your backend, proxying requests from the client app as necessary.

@girishw
Copy link

girishw commented Feb 27, 2020

@iainmcgin I, too, am running into this issue trying to support Googe Sign in on Mac Catalyst. Has anything changed since your last reply 2 years ago?

@anyalir
Copy link

anyalir commented Jun 10, 2020

Just as a note to whoever happens to have the same problem. To enable PCKE, call

AuthorizationRequest authRequest = new AuthorizationRequest.Builder(...)
                .setCodeVerifier(CodeVerifierUtil.generateRandomCodeVerifier())
                // ... other config
                .build();

and then later make sure you derive the token req from the auth req:

authService.performTokenRequest(
                authState.getLastAuthorizationResponse().createTokenExchangeRequest(),
                authState::update);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants