Search code examples
authenticationoauth-2.0credentials

Where to store user credentials for resource owner authentication in Oauth2 Code flow?


I am creating a demo for the OAuth2 code flow, where I am implementing the client, the resource server, and the authentication server. In all the implementations I have seen, before letting the resource owner approve the client authorization request, the resource owner has to log in on the authentication server. This is necessary for the authentication server to know who requested access to the protected resources in the resource server.

I realized that this part is unrelated to the OAuth2 or OpenID Connect protocols. OAuth2 describes how the resource owner can authorize a third-party client to access his/her own data, but the authentication server login is implementation specific (and could even occur in a password-less way). OpenID Connect is an extension of OAuth2, but focuses on providing the necessary authentication info to the client.


So, in an OAuth2 context, I thought of 2 possible user-credentials-based implementations for the authentication server login:

  • The authentication server can access to a data-store containing rows of type

    id, username, hashed_password

    When the resource owner logs in, then the auth server can validate the credentials using the above data-store. The problem with this approach is that I have to maintain a mapping between each user in this data-store and the corresponding users in the resource server store.

  • The data related to a certain user (including the username and hashed password) are kept in the resource server exclusively. This means that the authentication server must query the resource server to validate the user-credentials submitted by the resource owner during login. Aside from the cost of the additional RTT, putting authentication information in the resource server seems unfitting to me. After all, user and password are bound to a non-functional requirement (security). Am I mistakenly considering the resource server purpose?

Are these reasonable approaches? Which one fits better in the OAuth2 model? How is this commonly handled by the most popular OAuth2 services?


EDIT: ChatGPT Answer

While waiting for an answer, I interviewed ChatGPT, which agrees with me that the second approach is incorrect. This is its explanation:

The resource server should not store the password of a user in the context of the OAuth 2.0 protocol. In the standard OAuth 2.0 flow, the authentication of the resource owner (user) is handled by the authentication server. The authentication server is responsible for verifying the user's credentials, such as their username and password, and issuing an access token to the client (application) on behalf of the user.

The resource server must be able to associate the access token with the user data that it hosts. Typically, the authentication server includes some user information (such as the user ID or email address) in the access token payload, which the resource server can use to identify the user and retrieve any necessary data. The resource server, on the other hand, should only receive and verify the access token provided by the client in order to determine whether the client is authorized to access the requested resources. The resource server does not need to know the user's password as it does not perform the authentication itself.

The authentication server could store the user's email and password (in a securely hashed and salted form) and associate it with a unique user ID. This user ID can then be used to associate the user data stored on the resource server with the access tokens issued by the authentication server.


Obviously, a more complete (and reliable) answer is more than welcome, perhaps including the sources.


Solution

  • It is worth clarifying terminology also and looking at the original RFC6749 specification. In particular the role of the authorization server, which outsources a lot of the difficult security:

    • It implements protocols like OAuth 2.0 and OpenID Connect
    • It provides endpoints your apps and APIs to call
    • It provides many ways to authenticate
    • It issues tokens containing user identities

    In an OAuth 2.0 architecture you plug in an authorization server provided by security experts, eg a cloud or Docker based system. I would avoid the term authentication server.

    There are then typically two sources of user data that you need to match up:

    • Accounts from the authorization server
    • User identifiers mapped to business resources

    My blog post walks through some ways to match OAuth user IDs to business resources. You get rich security capabilities from the authorization server, but you need to deal with a more separated architecture.