OAuth and OpenIDConnect both aim to move the web into a standard of having a password-less web for authentication. For the most part, The most trusted identity providers still, at the core, rely on using a set of user credentials (username & password) to authenticate users. This is to gain federated access to whatever web service in an easy manner. The nice thing about this architecture is that the identity provider is quite agnostic to who or what requires identity, just as long as they implement the appropriate delegation access protocol properly, it will all be smooth sailing. Most of the time when you log in via the identity provider, you pass in your user credentials to the identity provider and not the client application. This is a good design since the relying client application does not need to (and should not) deal with user credentials.
What is wrong with the resource owner password grant?
The problem with the resource owner password grant or flow is that it does not particularly follow the password anti-pattern that the other grants in OAuth/OpenIDConnect follow. This is the only grant that permits the flow of password credentials through the client itself. The other flows require that the credentials go through the identity provider which guarantees that at the very least, your credentials go through ONLY a trusted provider and not both a client and the provider. What safety assertions can we make about the client which is essentially a pass-through for a set of credentials? well not much really. And that is where the problem with this grant type lies.
Figure 1: Resource Owner Password Credentials Flow.
The flow goes as illustrated in figure 1:
- The resource owner provides the client with its set of credentials.
- The client does a post request to the token endpoint of the identity provider where it supplies as part of the request the resource owner credentials.
- The identity provider then passes back to the client an access token.
The main issue lies between points 1 and 2. There we have the client, how do we know that this client is treating the credentials with the appropriate measures? How do we know that the client has not been compromised? Even on a less malicious note, how do we know that the client isn’t accidentally logging the credentials somewhere?
The method through which the client obtains the resource owner credentials is beyond the scope of this specification. The client MUST discard the credentials once an access token has been obtained.
At the end of the day it is really at the behest of the client to take care of the credentials in an ethical manner. Not only that, but you have to assume that the client has not being compromised in some form.
Why do we have this resource owner grant?
To put it simply, this grant type is here or one of three reasons. The first two reasons are outlined by the specification and the third one is something that somebody mentioned in a stackoverflow reply to one of my comments which I found peculiar.
Reason #1 You are stuck with a legacy system. For reasons attributed to how aged a product is, you cannot migrate it to use the specification’s anti-password pattern.
Reason #2 You are busy migrating a system from some older standard or some older authentication scheme such as HTTP Basic.
Reason #3 Your client does not have a browser but needs some form of user authentication. In this post a gentleman remarked that Apple TV has no browser context so to speak so it is impossible to initiate the other grant types.
However, at the end of the day, you need to trust the end to end link between the resource owner and the client. If that trust cannot be established, then you might be out of luck. I would say that use this grant minimally, know why it is here, and understand its risks. Once you got that under your belt you can make educated decisions about whether your situation warrants the use of this grant type. I do use it, it has its uses for some of our requirements, but the vast majority of scenarios that I deal with stay clear of this grant type.