Reputation: 311
after trial and error it seems to me that Google OIDC does not support the code flow without supplying the client secret: https://developers.google.com/identity/protocols/oauth2/native-app#exchange-authorization-code
According to the latest best practices for SPAs (https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-13), code flow + PKCE is the recommended way to handle authentication. Is anyone aware of any trick required to make Google's code flow accept the code_challenge rather than the client_secret? Perhaps a dummy secret?
Upvotes: 27
Views: 10212
Reputation: 36634
https://stackoverflow.com/a/78414957/80901 describes a workaround:
I then specified that my app is UWP type (even though it isn't). The credentials Google generated include a client id and a client secret, just as was the case when I had registered my app as Desktop type. However, now when I authorize the user (.NET library Google.Apis.Auth.OAuth2) it doesn't matter if I omit the client secret in my token request or even put in some bogus value for the client secret.
I have not yet verified this by myself, but will update this answer then.
Upvotes: 0
Reputation: 1606
Note that google on it's OIDC configuration enpoint mentions that it supports both plain and S256 as PKCE code challenge methors. I just tested using the code flow in google using both the client secret and passing the code_challenge and code_verifier in the relevant oath steps.
Here my observations at the time of writing
For completeness this is the error message that you get if you use the code flow with client credentials and invalid code verifier:
{
"error": "invalid_grant",
"error_description": "Invalid code verifier."
}
So you can use PKCE for extra security if you just send the code challenges and verifiers together with the client secret.
Upvotes: 1
Reputation: 154
A good alternative IMHO consists in using Keycloak as IDP and then adding Google to the delegate identity providers of your Keycloak instance (and then Facebook and then any other idp if required). Keycloak implements the PKCE flow or whatever flow in the Oauth 2 RFCs in a reliable way. That means you need a hosted instance of Keycloak though.
Upvotes: 2
Reputation: 2283
As of August 2020 the best practices document cited is still in draft and being activly updated - head revision here: https://datatracker.ietf.org/doc/draft-ietf-oauth-security-topics/. Googles' OAuth2 implementation has not yet applied the "work in progress" recomendation of PKCE being applied to web applications. SPAs are still directed to use the implicit flow in Googles' online documentation: https://developers.google.com/identity/protocols/oauth2/javascript-implicit-flow).
The standard for PKCE (https://www.rfc-editor.org/rfc/rfc7636) details that it was developed as a mitigation for authorisation code interception attacks found on mobile platforms and was originally recommended for implementation by native clients. Google's documentation for "Mobile and Desktop apps" does direct developers to use a PKCE Authorization Code flow. Clients using Google Android, iOS or windows store credential types with PKCE may omit the client_secret
(see the note on the refresh token parameter table - and confirmed by Cristiano).
It is now recognised that PKCE eliminates the need for any public clients to store a client secret, and as such can be used to deprecate the implicit flow which always had the flaw of including returned access and identity tokens in a redirect URI. https://developer.okta.com/blog/2019/05/01/is-the-oauth-implicit-flow-dead.
The draft IETF document states in section 2.1.1 that this recognition is likely to become a published standard.
Hopefully Google will update its implementation to remove the requirement for a client_secret
for a PKCE token request when the best practices becomes accepted. In the meantime it seems we have no choice but to continue writing SPAs using the implicit flow.
Upvotes: 20
Reputation: 1813
Well, I'm using openId Connect authorization code with pkce without using client_secret in an android app using this lib: https://github.com/openid/AppAuth-Android.
I just had to ensure that the custom scheme was set using the app's package name from the manifest and use it to register the android credential on google console.
Upvotes: 2