Technical Study: OAuth 2.0 Integration Into Hydro Raindrop

Hydrogen
Hydrogen
Published in
8 min readApr 4, 2018

A Project Hydro Case Study

This post is for developers that are curious to see an example of how Hydro Raindrop gets deployed in real-world applications. What better way to see that than in the Hydrogen platform itself!

Below, we examine a technical case study of how the Hydrogen core development team has integrated traditional OAuth 2.0 authentication and authorization methods, API keys, and whitelisting, into the Hydro Raindrop.

Below, we examine a technical case study of how the Hydrogen core development team has integrated the Hydro Raindrop with our traditional authentication methods, API keys, and whitelisting.

It is important to note that Hydrogen introduces additional security layers (“factors” for the remainder of this post) first before any API keys are validated.

All Hydrogen API partners must first have the IP of their various environments whitelisted by Hydrogen. Any attempt to validate an unknown IP is rejected. Another important note is that all exchange of calls between the client and Hydrogen APIs are encrypted and transmitted through the HTTPS protocol.

After validating API keys, integration with REST APIs involves partner authentication as an additional factor. Typically, this is done through an industry-standard authentication protocol such as those listed below:

● OAuth v2

● JWT (JSON Web Tokens)

The choice of authentication protocol depends on the partner’s environment and their familiarity with each type of authentication, as each type requires some integration effort. Once the decision is made, the type of authentication needs to be passed as an environment variable parameter at launch of the Hydrogen platform. The following table summarizes these options:

For instance, if the choice is to use JWT, then the command line to use would be:

● Java runtime command: java –jar hydrogen-x.x.x.jar –spring.profiles.active=prod,jwt

● Maven command: mvn spring-boot:run –Dspring.profiles.active=prod,jwt

OAuth2

OAuth (Open Authorization) is an open standard for token-based authentication and authorization. It defines four authorization grant types. Each type is useful in different cases. Hydrogen supports the “Resource Owner Password Credentials” grant type. The following diagram explains the authorization flow:

1. The partner initiates the authentication by sending a POST request to the /oauth/token endpoint providing the API username and key provided by Hydrogen as a query string in addition to a basic authorization header for the same credentials. The request would look similar to the following:

POST /api/oauth/token?grant_type=password&username=hydrogen-demo&password=lodluih2208uhb21ovpoy39891hbf HTTP/1.1

Host: www.example.com:9080

Authorization: Basic aGVkZ2VhYmxlLWRlbW86YWJkbHVpaDI5MDh1aGIyM292Ym95Mzk4NDFoYmY=…

2. The credentials are checked against the database. If valid, a new temporary authorization access_token is generated and returned to the requester together with a refresh_token (which needs to be stored on the client side) and a validity period. This token will have to be included in all subsequent calls to the server, as explained in the next step. A sample successful authentication from the server would look like the following:

{

“access_token”: “8004dd2b-9abc-4259–962f-0a2c29343ca9”,

“token_type”: “bearer”,

“refresh_token”: “2b451b71–0416–4d2b-a4ff-4884a07ae985”,

“expires_in”: 899,

“scope”: “read”

}

3. To make a call to an endpoint (for example /api/accounttypes), the request would have to look like the following snippet.

GET /api/accounttypes HTTP/1.1

Host: www.example.com:9080

Authorization: Bearer 8004dd2b-9abc-4259–962f-0a2c29343ca9…

Notice how the word “Bearer” prefixes the access_token value. This is required.

4. When the token expires, the client has to submit a new request of grant_type=refresh_token using the refresh_token value from step 2.

POST /api/oauth/token?grant_type=refresh_token&username=hydrogen-demo&password=lodluih2208uhb21ovpoy39891hbf&refresh_token=2b451b71–0416–4d2b-a4ff-4884a07ae985 HTTP/1.1

Host: www.example.com:9080

Authorization: Basic tGVkZ2VhYmxlLWRlbW86YWJkbHVpaDI5MDh1aYIyM292Ym81Mzk4NDFoYmY=

A new token is generated and sent back. Here is an example:

{

“access_token”: “b75e4355–5fc1–4e1c-a8fc-98eaba538c2f”,

“token_type”: “bearer”,

“refresh_token”: “2b451b71–0416–4d2b-a4ff-4884a07ae985”,

“expires_in”: 899,

“scope”: “read”

}

JSON Web Token (JWT)

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. The following flow explains Hydrogen’s JWT implementation:

1. The partner initiates the authentication by sending a POST request to the /authenticate/jwt endpoint, providing the API username and key provided by Hydrogen in the body of the request. A sample request would look as follows:

POST /api/authenticate/jwt HTTP/1.1

Host: www.example.com:9080

Content-Type: application/json

Cache-Control: no-cache

{

“username”:”hydrogen-demo”,

“key”:”abdluih2908uhb23ovboy39841hbfx”

}

2. The credentials are checked against the database. If valid, a new temporary authorization token is generated and returned to the requester. This token will have to be included in all subsequent calls to the server, as explained in the next step. A sample successful authentication from the server would look as follows:

{

“response”: “ eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJJbnRlZ3JhdGlvblRlc3QiLCJhdWRpZW5jZSI6IndlYiIsImNyZWF0ZWQiOjE1MDcyMTMyNjcxMjgsImV4cCI6MTUwNzgxODA2Nywia2V5IjoiSW50ZWdyYXRpb25UZXN0In0.0w-”

}

3. To make a call to an endpoint (for example /api/accounttypes), the request would have to look as follows:

GET /api/accounttypes HTTP/1.1

Host: www.example.com:9080

X-Auth-Token: eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJJbnRlZ3JhdGlvblRlc3QiLCJhdWRpZW5jZSI6IndlYiIsImNyZWF0ZWQiOjE1MDcyMTMyNjcxMjgsImV4cCI6MTUwNzgxODA2Nywia2V5IjoiSW50ZWdyYXRpb25UZXN0In0.0w-…

4. When the token expires, the client has to submit a new GET request to the endpoint /authenticate/jwt/refresh with the same token used in the previous steps. For example, if we use the token in the example above, the request would look as follows:

GET /api/authenticate/jwt/refresh HTTP/1.1

Host: www.example.com:9080

X-Auth-Token: eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJJbnRlZ3JhdGlvblRlc3QiLCJhdWRpZW5jZSI6IndlYiIsImNyZWF0ZWQiOjE1MDcyMTMyNjcxMjgsImV4cCI6MTUwNzgxODA2Nywia2V5IjoiSW50ZWdyYXRpb25UZXN0In0.0w-

It is up to the client to decide how to handle token refresh. There are multiple approaches:

A. Request a new token only when a request to an endpoint fails due to token expiration.

B. Routinely request a new token before the expiration of the current token.

Adding a Blockchain Immutability Layer

We have now established a general framework for a multi-factor authentication protocol in a private REST API.

Now, let’s examine how an additional layer can be achieved via the public blockchain. The consensus mechanisms and immutability of the blockchain provide transparency, but more importantly they provide vectors for mitigating data loss and breaches, as well as preventing unauthorized access to APIs.

With Hydro, authentication is based upon transactional operations on the Ethereum blockchain. API users are validated by initiating particular transactions, with particular data payloads, between particular addresses. Below is a workflow detailing how the Hydro authentication process works, from the perspective of an API user:

1. Initialization

a. Register your Hydro wallet address

b. Call an API service that generates transactional parameters

2. Authentication

a. Conduct a transaction from the registered wallet to the Hydro smart contract address (with given parameters)

b. Call an API service to get authenticated

c. Get an auth token (if your Hydro transaction was valid)

3. Enforcement

a. Use the auth token, in addition to satisfying other security factors, when utilizing API services

b. Renew the token when it expires

We have created a diagram, shown below, which has this user flow:

Preventing Hackers

Using Hydro here has solved many problems. First and foremost, it has provided the public check and balance that is missing in financial services applications. Is the person accessing this private data who they say they are? If so, they have to prove it. If not, they are automatically rejected.

To understand it, we will now show what will need to be done to gain access to the API:

1. Hacker must access or imitate the user’s whitelisted IP address

2. Hacker must steal the user’s base Hydrogen API credentials

3. Hacker must steal the user’s Hydro multi-signature wallet

4. Hacker must imitate the user by conducting a valid Hydro raindrop transaction

If any of these steps create a failure, the user is immediately locked from the API access. The Hydrogen team encourages users to hold wallet addresses and keys in multiple locations, so there is not a single point of failure. An ill-doer can not randomly guess any of the security factors, because there are literally trillions of unique combinations.

A properly secured multi-signature wallet is not only difficult to steal, but the public nature of the blockchain also allows for instant recognition of any theft as it relates to the security of the API. Anyone in the world can view an authentication attempt to the Hydro smart contract, and thus the days of platforms being compromised for days, weeks, or months on-end are gone. API hackers can now be thwarted with immediacy because of the ability to detect unexpected authorization attempts in real time, from anywhere in the world.

A Look Into Hydrogen’s Implementation of Hydro

Hydrogen has implemented our own authentication system with OAuth 2.0 and Hydro’s Raindrop. This implementation is done through a server which relays called between both an OAuth server and the Hydro server.

Let’s take a further look at how this works:

  1. The user registers an ethereum address by sending a GET request to /whitelist. This request must provide an ethereum address. The server will then relay that request to the Hydro API along with Hydrogen’s username and key. If the username and key are validated, the address is routed to a connector which calls the smart contract method “whitelistAddress” and saves the address in an immutable array of valid, whitelisted addresses. This then returns a hydro_address_id which is used for subsequent calls to the Hydro ecosystem.

POST /whitelist?address=0x123456789

Host: www.example.com:9080

{

123

}

2. The user is now able to authenticate through the Hydro API. To initiate an authentication, they must send a GET request to /challenge. The user must send the query parameter hydro_address_id which was received from the whitelist call. Like the previous call, when relaying this request to Hydro, Hydrogen must send their username and key in the body of thew request. The Hydro API generates a quantity of HYDRO and a random challenge string (i.e. the transactional parameters). The HYDRO amount is then routed to the smart contract along with the platform that is authenticating a user and stores them in a map. Meanwhile, the challenge string is stored in the Hydro database. The user is returned all three values.

GET /challenge?hydro_address_id=1

Host: www.example.com:9080

{

“amount”: 10,

“challenge_string”: “FHENNFU7SJB”,

“partner_id”: “1”

}”

3. With this information, the user performs a transaction on the blockchain. This step is handled by the user and does not interact directly with the API, for added security. The user specifies the transaction to call the smart contract function “authenticate”, which requires a value, a partnerId, and a data string. From the previous response, the value is the amount, the partnerId is the partner_id, and the data string is the challenge string. These values are stored in a separate map in the smart contract.

4. After executing this transaction, the user can GET to /token/client_credentials, /token/password, or /token/refresh based on their OAuth credentials. This call requires the hydro_address_id along with all other required fields for the selected OAuth method. Here, Hydrogen must now do two relays. First, they once again relay to the Hydro API which requires the username and key. The API checks whether or not the smart contract has validated the transaction, which only occurs if the previously registered address, the H2O amount, and the challenge string all match precisely. A boolean is returned which indicated the success of the raindrop. From here, Hydrogen routes a second call to the Hydrogen OAuth server to request a token. Assuming this request contains the correct credentials, this returns a token.

POST /token/password?hydro_address_id=1&client_username=clientuser&key=key&username=user&password=pass

Host: www.example.com:9080

{

“access_token”: “b75e4355–5fc1–4e1c-a8fc-98eaba538c2f”,

“token_type”: “bearer”,

“refresh_token”: “2b451b71–0416–4d2b-a4ff-4884a07ae985”,

“expires_in”: 899,

“scope”: “read”

}

5. The token remains valid for 24 hours. It is required for every API call, including those related to the manipulation and retrieval of sensitive client data. Upon expiration, the user has to complete the authentication process again by conducting a new Hydro transaction that satisfies new transactional parameters.

--

--

Hydrogen
Hydrogen

The Global Financial Operating System. Creator of #Atom and #Molecule #APIs. Founding dev on open-source #blockchain #Hydro. Made in #NYC! www.hydrogenplatform.