How are resource owner credentials stored in OAuth2

authenticationoauth2

I have been researching oauth2 as of recent and trying to draft an implementation plan. However I seem to be missing something, or something hasn't quite clicked yet.

I plan on creating an api and having certain endpoints be protected, requiring authorization. This api will be accessed via my 1rst party web application utilizing javascript/vuejs.

To accomplish this, the "Resource Owner Password Flow" seems to be the best choice for allowing resource owners to authenticate to gain access to parts of the api. The specific implementation I have chosen to use for oauth2 is laravel's "Passport". Example code for the password flow is below as well as the table layout which this implementation uses:

$response = $http->post('http://your-app.com/oauth/token', [
    'form_params' => [
        'grant_type' => 'password',
        'client_id' => 'client-id',
        'client_secret' => 'client-secret',
        'username' => 'taylor@laravel.com',
        'password' => 'my-password',
        'scope' => '',
    ],
]);


+-------------------------+
|oauth_clients            |
+-------------------------+
|id                       |
|user_id                  |
|name                     |
|secret                   |
|redirect                 |
|personal_access_client   |
|revoked                  |
|updated_at               |
|created_at               |
+-------------------------+

+-------------------------+
|oauth_auth_codes         |
+-------------------------+
|id                       |
|user_id                  |
|client_id                |
|scopes                   |
|revoked                  |
|expires_at               |
+-------------------------+

+-------------------------+
|oauth_access_tokens      |
+-------------------------+
|id                       |
|user_id                  |
|client_id                |
|name                     |
|scopes                   |
|revoked                  |
|created_at               |
|updated_at               |
|expires_at               |
+-------------------------+

+-------------------------+
|oauth_refresh_tokens     |
+-------------------------+
|id                       |
|access_token_id          |
|revoked                  |
|expires_at               |
+-------------------------+

+------------------------------+
|oauth_personal_access_clients |
+------------------------------+
|id                            |
|client_id                     |
|updated_at                    |
|created_at                    |
+------------------------------+

In the example request above, a client_id and client_secret are required along with username and password. I fail to see how calling http://your-app.com/oauth/token with the provided parameters would allow a resource owner to authenticate, since there is no table that stores a resource owner's username and password.

Could someone explain to me what is happening here, or what pieces of the puzzle I am missing? Should the OAuth2 authorization server be tied to my api (resource server) in some way that allows the authorization server to authenticate user's based on their username and password?…

Best Answer

Should the OAuth2 authorization server be tied to my api (resource server) in some way that allows the authorization server to authenticate user's based on their username and password?...

It depends on the needs, but yes, that's a fairly common implementation. However, it has led many people to believe that OAuth2 is an authentication protocol too; when it's not.

As an additional confounder to our topic, an OAuth process does usually include several kinds of authentication in its process: the resource owner authenticates to the authorization server in the authorization step, the client authenticates to the authorization server in the token endpoint, and there may be others. The existence of these authentication events within the OAuth protocol does not translate to the OAuth protocol itself being able to reliably convey authentication.

-oauth.net-

The OAuth2 goal is to allow applications to inter-operate without having to share credentials. Without having to care about users. OAuth2 doesn't care how users are identified. It only expects tokens and the issuers of the tokens for further validations.

I fail to see how calling http://your-app.com/oauth/token with the provided parameters would allow a resource owner to authenticate, since there is no table that stores a resource owner's username and password.

That's because the credentials validation (authentication) should be delegated to someone else.

This someone else can be either your own application (for example a login endpoint) or an external one. For example Facebook, Google, Github, etc.

Say we have a web application named MyApp.com. We would like to allow new users to get registered and authenticated quickly by getting the data from some other applications we trust. For example, from Facebook accounts.

Obviously, we cannot ask users for their Facebook credentials. Instead, we delegate the hard job to Facebook. Our authentication process will redirect to Facebook's OAuth.

Users will log in to Facebook and grant us access to their profile data.

Facebook will generate a token as proof of a) user identity and b) privileges over the user account. This token is what we know as ID token.

ID tokens are sent back to Facebook every time Myapp.com needs to inter-operate with Facebook.

After getting the ID token, the very first thing we do is to request the Facebook user profile. We send the ID token in the request. If Facebook accepts the token, we complete the registration/login and allow users to pass.

On the other hand, MyApp.com also has its own registry and log-in. If users send MyApp.com credentials, who do you guess is going to be the Identity Provider? You guess right. MyApp.com itself. As we see, authentication and authorization are different things.

How are resource owner credentials stored in OAuth2?

According to the above options, the credentials can be stored in your own application, in a centric and shared Identity Provider (also known as Federated Identity Provider) or they could be stored nowhere within your domain (Facebook, Google, etc).

Considerations

If your application is the only consumer of authorization, consider changing the auth model for something simpler (e.g JWT) and also consider having the service integrated within the application. Ultimately, it's just the application's auth service.

Related Topic