Objective
My goal is to implement a generic mobile client and backend authentication flow, just for practice. Imagine that I am building a note app that stores user notes on the backend. Instead of implementing my own user management in my backend, I want to rely on some popular OIDC providers to authenticate users from my backend.
The important thing is I am not interested in accessing any user data that OIDC Provider offers. My goal is to verify the user and the client whenever something hits my backend.
My understanding of OIDC Authentication flow is as follows:
IdProvider
: the oidc providerMyClient
: mobile application. hasclient_id
MyBackend
: hasclient_secret
Steps:
MyClient
generates PKCE code challenge.IdProvider
authenticates the user andMyClient
receives a temporaryauthorization_code
.- (not sure on this)
MyClient
sendsMyBackend
both the tempauthorization_code
and the PKCE code verifier for token exchange. MyBackend
does token exchange with theIdProvider
.- (also not sure on this)
MyBackend
sendsid_token
andrefresh_token
back toMyClient
.
My justification on step 3 and 5 are this:
- Only
MyBackend
can accessclient_secret
. Therefore token exchange can only be done byMyBackend
andMyClient
is responsible for sending the tempauthorization_code
and the PKCE code verifier. MyClient
needsid_token
to hit normalMyBackend
endpoints.MyClient
also needsrefresh_token
to initiate the token refresh flow in caseid_token
expires.
Problem
Now in above flow it looks like there is no way I can prevent an attacker from stealing the client_id
and impersonate MyClient
. I have tried to search for sample implementation on the internet but many of them simply rely on the client-side authentication only. For example, this one: https://github.com/awslabs/aws-sdk-android-samples/tree/master/AmazonCognitoAuthDemo asks you to store client_secret
in the client side.. I am not sure why this is acceptable and AWS even built a sample for it?
Any help would be appreciated.