Few notes on top of above message exchange. While it is true that oauth is designed to permit server-server interactions the key point is semantics of what or who these servers are. I believe this is the key to understand how it should work. I had multiple attempts towards oauth 2 and only when I sorted out my head about component roles it become clearer to me. Reading code of any oauth client is much simpler when terminology is stabilized.
I do not wish to start an encyclopedia on it. Take it as “plain man understanding of oauth”. If you have a closer look on oauth there are several things:
- Authorization Server, place which confirm user identity and ship tokens,
- Resource Server, which holds data accessible for an user and require token to release it
- Client Application, which in practice could be another server instance or just a browser instance on user device.
This triangle forms three angles which user is familiar this or other way. Finally interactions between these elements and sequence of them define so called oauth “flows”.
Because oauth defines “resource server” element there is obviously also a “resource instance” and “resource owner”. In most of situations the owner part or even an resource is being omitted yet it is in some ways inherent to deployments unless we rely on oauth (actually openid connect, cause oauth is fairly limited in this field) just to proof user identity. The resource owner is usually user of the system, however if we dive more it might be that actual user receives a grant from another owner (ie. thins defined by UMA specification). The result of working authorization sequence can be summarized into single phase
the user grants a permit (represented by refresh token) to his resources held by certain server to an end application (client).
Now, when we look at most common flows we will find few. One is called called authorization code flow (historically called 3-legged in oauth 1), resource owner credentials flow (refereed also as password credentials), client credentials (historically called 2 legged), implicit and also device flow.
Looking at authorization code - in many situations it is best suited for server applications, hence it is extensively used when we have a standalone application which has separate communication path to authorization server. Yet, it also requires client application to expose an public endpoint.
Main advantage of device flow compared to above is that it allows user to confirm that certain device has access to its data (or produce data on behalf of an user) without necessity for this user to launch browser session on that device. Quite often issue on small devices is that device on which oauth client is working might not have a keyboard available. They also have limited capabilities to display information, thus code is just few characters. Another point to note - device flow does not require device to expose any endpoint as whole process is based on associated HTTP calls happening over two separate communication paths -
device -> authorization server and
user -> authorization server.
Anyhow, that would be it
The client code I wrote works with any server which is compatible with device flow. You can test it by creating file called
org.connectorio.cloud.device.auth.cfg (next to
org.ops4j.pax.logging.cfg) with following contents:
authURI=<place to obtain device code>
tokenURI=<place to obtain token>
I am actually curious if you will get it running with your provider. If you’re up for a test then I can help you getting client deployed. I found for example that client id should be somehow dynamic if you have multiple devices owned by same user account. If you use same client id/user account then SSO session retained by user browser can propagate information from one device in context of another. Spec does not cover that yet authorization served I worked with didn’t like that at all!