This is a very simple idea but practical - OAuth2AuthorizedClient should take a usernameOfRegistration for the ClientRegistration.
OAuth2AuthorizedClient has a ClientRegistration and the principalName - nothing wrong here. Well, in practical, a user has a username or account_id within the Registration (such as Google, Facebook, Github). Therefore, in practical, our application and database usually wants to record all users' google_user_id, facebook_user_id, github_user_id etc. It's also possible a user might have more than 2 github accounts associated with our application; therefore, a single principalName is not enough to distinguish this.
So my suggestion is add this private final String usernameOfRegistration; to this class OAuth2AuthorizedClient, and update the related Repository,Service, subclass accordingly with the oauth2-client-schema.sql,etc.
Please consider! If there is anything unclear or anything doesn't make sense, please let me know.
Comment From: jgrandja
@jhcao23 Adding OAuth2AuthorizedClient.usernameOfRegistration is not necessary as the "username" is already available via OAuth2User.getName() or OidcUser.getName() after completing HttpSecurity.oauth2Login().
For example, OAuth2AuthenticationToken.getName() will return DefaultOAuth2User.getName() or DefaultOidcUser.getName(), which is the same as OAuth2AuthorizedClient.principalName. This is the unique identifier of the user registered at the provider. For Google, this will map to the sub claim (by default) and for GitHub this will map to the id attribute - see CommonOAuth2Provider.
Also, see ClientRegistration.ProviderDetails.UserInfoEndpoint.userNameAttributeName in the reference
Furthermore, not all authorization grants support a user-based flow. For example, the client_credentials grant is used by client only, therefore, the generic name OAuth2AuthorizedClient.principalName can be used for user and non-user flows.
I'm going to close this but if I misunderstood your request we can always re-open to discuss further.
Comment From: jhcao23
Hi @jgrandja I understand your point. You didn't misunderstand me however, there is an additional question - when we design our datastore structure, where or which table|column shall we store this unique identifier of the user registered at the provider? I assumed this idOfProvider should be stored, as oauth2-client-schema.sql indicated, in the table oauth2_authorized_client thus accordingly reflect to the class OAuth2AuthorizedClient. If client_credentials is applied we could left that field blank. Anyway, in one word, my concern is how to store this idOfProvider in database.
Comment From: jgrandja
@jhcao23 The oauth2_authorized_client (oauth2-client-schema.sql) table defines the principal_name column, which would store the unique identifier of the user/client registered at the provider. If you want to customize the table definition and store additional data (and column) then take a look at the test JdbcOAuth2AuthorizedClientServiceTests.tableDefinitionWhenCustomThenAbleToOverride(), which demonstrates how to customize the table definition.
Comment From: jhcao23
oh I thought principal_name is the username or similar in our own system. Thank you @jgrandja for your note. very appreciated!