This was a collaboration project for learning oauth2orize and passport. The concept involves setup of a home network Oauth 2.0 server that could be used to restrict access to a personal web server, database API, and home network IOT devices. This repository will use the oauth2orize library. Users records and sessions can be temporarily stored in memory during development or configured to use PostgreSQL. This is a learning project written in 2021. The project will require additional work before considering use in a production. No formal release has been issued.
Repository | Description |
---|---|
collab-auth | Oauth 2.0 Authorization Provider, redirect login, tokens |
collab-frontend | Mock Web server, reverse proxy, HTML content |
collab-backend-api | Mock REST API using tokens to authorize requests |
collab-iot-device | Mock IOT Device with data acquisition saved to DB |
The initial starting point for this application was copied as a template application from Oauth2OrizeRecpies by Frank Hassanabad https://github.com/FrankHassanabad/Oauth2orizeRecipes.
The primary motivation for this project was to discover how oauth 2.0 works by attempting to implement Oauth 2.0 on a personal web server and use it restrict access to IOT devices on a home network.
First, there is already an excessive quantity of resources on the internet that explain Oauth 2.0, so that will not be reproduced here. For me, this was a learning project, not a teaching project. None the less, I have been asked to share my example because it because it may be interesting or useful.
When I started looking at Oauth 2.0 tutorials, I soon discovered a frequently used phrase "implementation dependent". For example, what standard data should go in an access token? Well, tokens are implementation dependent. How about granular permissions such as "scope"? It is the same, scopes and permissions are implementation dependent. It appeared that Oauth 2.0 was much more of an abstract concept than I had assumed. The only way truly understand it would be to implement it and solve each of these details, one by one, as choices came up.
I am a huge fan of raspberry pi projects. At times, I have had up to 15 pi active on a home network. From a hobby perspective, setting up a web API on a raspberry pi is a very simple way to read sensor data from the network. This allows data from home IOT devices to be easily displayed from within a personal web page. The data can be saved in a database, and used to make various charts on the web page. For mobile phone access, the web server and database live in a cloud based server. This project seemed to be a great solution to manage access control for various personal web pages, databases, and home network IOT devices.
My personal web pages were put together using an Express.js web server running under Node.js on a Debian Linux server. I was most comfortable with a solution that could run in that environment.
Oauth2orize - Primarily based on download popularity, I decided to use oauth2orize. OAuth2orize is an authorization server toolkit for Node.js that can be used to implement the OAuth 2.0 protocol. Oauth2orize is truly an amazing library. I really enjoyed discovering it's capabilities and exploring it's various functions. Internally, it has a lot of critical security functionality that probably should be left to programmers more experienced than myself. It was a good fit for my use case.
Oauth2orizeRecipes - It's best to start with an example. I found Oauth2orizeRecipes and used it as a template to start the project. It contained an example Express web server that integrated into oauth2orize with examples of all four oauth 2.0 grant types. Unlike other Oauth 2.0 examples, Oauth2orizeRecipes installed and ran, out of the box. The code was well commented and easy to understand.
Passport - Passport is an authentication middleware for express/node.js. Expanding on the examples in Oauth2orizeRecipes, passport is an elegant way to insert authentication into an express server request/response flow as an express middleware. Passport has individual "strategy" modules that fully support Oauth 2.0. However, since this was a learning project, it is also instructive to replace some of the passport middleware with custom code. The collab-backend-api and collab-iot-device do not use passport.
Postman - Actually, most of the coding on this project was done using Postman rather than a web browser. Once I had Oauth2orizeRecipes up and running, I started using postman from the first day. Most of early time was spent adding console.log() statements to both Oauth2orizeRecipes and oauth2orize as I stepped through the transactions of each Oauth 2.0 grant type. Unfortunately, in July 2023 Postman became inoperable due to removal of the scratchpad. The collections have been removed.
Authorization Server - Once I could reproduce all four grant types using postman, I created a github repository (collab-auth) to serve as the new authorization server for the project. The "/authorization-server/" folder from Oauth2orizeRecipes was used as a starting template. From there, the collab-auth repository evolved into an implementation that would fit the needs of a personal web server.
The following 3 repositories were created solely to demonstrate the authorization server.
Mock Web Server - A second github repository (collab-frontend) was created to hold a mock web server. Npm packages for passport, passport-oauth2 were configured to use oauth 2.0 authorization code grant. The purpose of the mock web server was to setup passport so the user's web browser would be redirected to authorization server for password entry, then redirected back to the mock web server URL with an authorization code. The web server then exchanged the code for an access_token which it stores on the user's behalf. It currently uses passport-oauth2 to obtain the first token, then upon expiration, use custom code to exchange refresh tokens for replacement access tokens.
Mock Backend API - A third github repository (collab-backend-api) was created. Code was setup to emulate a REST API with one data table where the data is stored using in-memory variables. The purpose of the mock REST API server is to accept HTTP requests containing an Oauth 2.0 bearer token. The token is validated by sending it to the authorization server before fulfilling the database query. One route is setup to demonstrate the use of scope restrictions on specific routes.
Mock IOT Device - Lastly, a forth repository (collab-iot-device) was created to emulate a raspberry pi IOT device on a home network. The purpose of the mock IOT device is to obtain an access_token using client credentials grant type and use the token to submit mock data to database in the mock backend API.
When all 4 repositories are working, an attempt to visit the demo web page will redirect the user to the authorization server to obtain an access_token. The token is then used to view a data table in the mock API which contains mock data submitted by the emulated IOT device.