OAuth Part 3 - Clients and Protocol Endpoints
What is the client?
This may be a little trivial, but it could cause a little confusion for some so we're going to go into it briefly. The client is the thing running the code that talks to the authorization and resource servers on behalf of the user. If the code is running on a web server, the web server is the client. If it's running in a web browser, the user agent running on the user's machine is the client. If it is a native app running on a smart phone, the native app is the client. Seems obvious, but the nature of the client has important OAuth considerations attached to it.
Clients and Confidentiality
As we've discussed, there are a few different types of authorization grants defined in the spec. Because of the extensibility provisions, there are actually a lot more that could exist. The credentials those grants represent have the potential to have very powerful authorization rights attached to them that go well beyond the
protected resources we're considering. For example, a username and password might unlock access to a lot of things. Accordingly, we have to think about how credentials are handled and secured by clients.
OAuth defines two types of clients, those that can be trusted to keep a secret and those that cannot. If the client is running on a server in a data center someplace, OAuth considers that client capable of keeping a secret and refers to it as a Confidential client. If, however, the client is running on a piece of hardware that the user has direct access to, like a web browser or a native client, OAuth doesn't trust those clients to be able to keep secrets and calls those Public clients. After all, not all users are trustworthy. If the user has the code and can sniff the traffic between the client and the servers, they can probably crack it open and reverse engineer the credentials.
The spec says that the following client types must register in advance:
- Public clients
- Confidential clients using implicit grants
It is possible for there to be such a thing as an unregistered client but "the use of such clients is beyond the scope of this specification and requires additional security analysis and review of its interoperability impact". This sounds like a case of a thing being both possible and a bad idea at the same time. We're going to proceed under the assumption that all clients must be registered with the authorization server first from here on out. The client needs to provide the authorization server with a couple of things:
- The client type (confidential or public) so the authorization server knows the limitations of the client's secret keeping abilities.
- Client redirection URLs - At the end of the authorization process, the authorization server is going to send the client something (an authorization code or a token of some sort). This URL is where that something is going to be sent. This is only required for the authorization code and implicit grants.
- The spec allows for the authorization server to demand additional information too as a part of the registration process.
In exchange, the authorization server will issue the client a client ID. This ID is unique to the registration, so a client capable of registering with more than one authorization server will need to juggle more than one client ID. This ID is not considered a secret by the spec so it should never be used as if it were. If the client is a confidential client, it's going to be issued a set of secrets during the registration process to authenticate with.
The spec is flexible enough that a lot of possible types of client could be imagined and still be valid, but it explicitly addresses three. Quoting from the spec:
- Web Application - A web application is a confidential client running on a web server. Resource owners access the client via an HTML user interface rendered in a user-agent on the device used by the resource owner. The client credentials as well as any access token issued to the client are stored on the web server and are not exposed to or accessible by the resource owner.
- User-agent-based Application - A user-agent-based application is a public client in which the client code is downloaded from a web server and executes within a user-agent (e.g., web browser) on the device used by the resource owner. Protocol data and credentials are easily accessible (and often visible) to the resource owner. Since such applications reside within the user-agent, they can make seamless use of the user-agent capabilities when requesting authorization.
- Native Application - A native application is a public client installed and executed on the device used by the resource owner. Protocol data and credentials are accessible to the resource owner. It is assumed that any client authentication credentials included in the application can be extracted. On the other hand, dynamically issued credentials such as access tokens or refresh tokens can receive an acceptable level of protection. At a minimum, these credentials are protected from hostile servers with which the application may interact. On some platforms, these credentials might be protected from other applications residing on the same device.
How do the various parties communicate with each other? This has been alluded to a few times now, but the spec calls it out specifically. There are three different endpoints defined which, depending on the nature of the client, are not all necessarily used.
- Authorization - Exposed by the authorization server to issue authorization grants to clients
- Redirection - Exposed by the client to receive authorization grants
- Token - Exposed by the authorization server to exchange authorization grants and refresh tokens for access tokens.
There are a lot of MUSTs and SHOULDs in the spec in this section to define the nature of the endpoints, their registration and their security. The key thing to understand is that this whole endpoint dance is part of how OAuth attempts to keep everything secure. We'll see how this works when we unpack each of the flows, but suffice it to say, this dance is necessary.
The Authorization Endpoint
This endpoint is exposed by the authorization server and is where the client comes to obtain an authorization grant. The resource owner will authenticate here using whatever mechanism the authorization server requires. At the end, it's going to respond with some sort of token, depending on the grant type.
The Redirection Endpoint
When the authorization server responds via the authorization endpoint, it's going to issue a redirect (normally a 302 but that's actually an implementation detail) to the client's redirection endpoint. This is where the client is going to receive whatever token or code the authorization sent in response to the call on the authorization endpoint. This needs to be defined in advance during client registration.
The Token Endpoint
The token endpoint is where the client is going to take whatever grant it finally received and try to exchange it for an access token. Alternately, if the client has a refresh token, it uses this same endpoint to try to exchange it for a fresh access token.
We've finally finished setting the table in terms of concepts and terminology so in the next couple of posts we actually get to look at the actual flows. Whew...