** DEPRECATED ** Getting Started with FOLIO for Developers
00: Introduction
: FOLIO Developer Curriculum Outline
01: Clone, Build, and Explore Okapi
02: Initialize Okapi from the command line
03: Enable Okapi Authentication
04: Deploy test Stripes module
05: Set up the Okapi Users app
06: Interact with the FOLIO Stable VM
All real-world uses of Okapi will need to provide authentication and authorization services. The Okapi Gateway itself does not handle these tasks; rather, it delegates them to one or more Okapi Modules that operates at an early phase of module requests orchestrated by the Okapi Gateway. In this lesson we will first interact directly with a sample authentication Okapi Module. Later in the lesson we will register and deploy the sample authentication module on the Okapi Gateway. Authorization will be covered in a later lesson.
Okapi-test-auth-module is a simple module that illustrates authentication in Okapi, and it comes with okapi-core.
In a terminal window, start the okapi-test-auth-module.
When using the VirtualBox method, you will need to open a terminal window on your host computer, change the working directory to the location of the Vagrantfile
, and use the vagrant ssh
command to connect from the host computer to the guest.
$ cd $FOLIO_ROOT/okapi
$ java -jar okapi-test-auth-module/target/okapi-test-auth-module-fat.jar
02:15:42 INFO MainVerticle Starting auth 26062@contrib-jessie on port 9020
02:15:42 INFO ertxIsolatedDeployer Succeeded in deploying verticle
The /login
path of okapi-test-auth-module takes a simple JSON document with a ‘username’ and a ‘password’ value.
In this test authentication module, if the password is the same as the username with the string ‘-password’ appended then the authentication is successful and a token is returned.
This can be demonstrated by using this curl command in a second terminal window to send a sample JSON document to the okapi-test-auth-module.
$ curl -i -w '\n' -X POST -H 'X-Okapi-Tenant: blah' \
-d '{"username": "seb", "password": "seb-password"}' \
http://localhost:9020/authn/login
HTTP/1.1 200 OK
Content-Type: application/json
X-Okapi-Token: dummyJwt.eyJzdWIiOiJzZWIiLCJ0ZW5hbnQiOm51bGx9.sig
Content-Length: 47
{"username": "seb", "password": "seb-password"}
Now try to send a JSON document in which the password does not match the expected value. Note that the response returns an HTTP 401 “Unauthorized” status.
Another path supplied by okapi-test-auth-module is /check
; it checks an X-Okapi-Token to see if it is valid.
$ curl -i -w '\n' -X GET -H 'X-Okapi-Tenant: blah' \
-H 'X-Okapi-Token: dummyJwt.eyJzdWIiOiJzZWIiLCJ0ZW5hbnQiOm51bGx9.sig' \
http://localhost:9020/check
HTTP/1.1 202 Accepted
X-Okapi-Token: dummyJwt.eyJzdWIiOiJzZWIiLCJ0ZW5hbnQiOm51bGx9.sig
X-Okapi-Module-Tokens: {}
X-Okapi-User-Id: seb
Content-Type: text/plain
Transfer-Encoding: chunked
Note that the response returns an HTTP 202 “Accepted” status. Try sending a request without the required X-Okapi-Tenant header. All requests are expected to send the X-Okapi-Tenant header.
Return to the terminal window with okapi-test-auth-module running and press Control-C to exit it.
The Okapi-test-auth-module is registered and deployed just like any other Okapi Module: using a ModuleDescriptor and a DeploymentDescriptor. In the terminal window, start the Okapi Gateway with debugging turned on:
$ cd $FOLIO_ROOT/okapi
$ java -Dloglevel=DEBUG -jar okapi-core/target/okapi-core-fat.jar dev
12:08:11 INFO MainVerticle git: git@github.com:folio-org/okapi 225c9c1e03c29459da430f93110abb30378e1394
12:08:11 INFO MainVerticle clusterManager not in use
12:08:11 INFO MainVerticle Proxy using inmemory storage
12:08:12 WARN Storage Storage.resetDatabases: NORMAL
12:08:12 INFO TenantWebService All tenants deployed
12:08:12 INFO MainVerticle API Gateway started PID 64161@Walkabout.lan. Listening on port 9130
Open up a second terminal window to send JSON documents to the Okapi Gateway using curl (noting that if you are using the VagrantBox method you will need to open a new terminal on your host and use the vagrant ssh
command).
The examples in this tutorial are using the in-memory storage, so you will need to resend the Okapi-test-module ModuleDescriptor and DeploymentDescriptor as well as redefine the testlib
tenant and enable the Okapi-test-module.
If you completed the previous lesson, these JSON documents are in the $FOLIO_ROOT
directory.
$ cd $FOLIO_ROOT
$ curl -i -w '\n' -X POST -H 'Content-type: application/json' \
-d @okapi-proxy-test-basic.json http://localhost:9130/_/proxy/modules
$ curl -i -w '\n' -X POST -H 'Content-type: application/json' \
-d @okapi-deploy-test-basic.json http://localhost:9130/_/discovery/modules
$ curl -i -w '\n' -X POST -H 'Content-type: application/json' \
-d @okapi-tenant.json http://localhost:9130/_/proxy/tenants
$ curl -i -w '\n' -X POST -H 'Content-type: application/json' \
-d @okapi-enable-basic.json http://localhost:9130/_/proxy/tenants/testlib/modules
This example of a ModuleDescriptor is similar to the one used for the Okapi-test-module.
$ cat > okapi-proxy-test-module-auth.json <<END
{
"id": "test-auth-3.4.1",
"name": "Okapi test auth module",
"provides": [
{
"id": "test-auth",
"version": "3.4",
"handlers": [
{
"methods" : [ "POST" ],
"pathPattern" : "/authn/login"
}
]
}
],
"requires": [],
"filters": [
{
"methods": [ "*" ],
"pathPattern": "/*",
"phase": "auth",
"type": "headers"
}
]
}
END
$ curl -i -w '\n' -X POST -H 'Content-type: application/json' \
-d @okapi-proxy-test-module-auth.json http://localhost:9130/_/proxy/modules
The significant difference is a new dictionary called filters
.
The filters
dictionary specifies paths and phases for which the Okapi Gateway will call this module.
At the moment, there is only one phase (auth
) and the methods
and pathPattern
specify that this module will be called for all Okapi Gateway requests.
Another difference is that the launchDescriptor
is omitted; as shown below, the launchDescriptor
can also be defined in the DeploymentDescriptor.
(This can be useful in cases where there are command-line options specific to a particular deployment.)
This example of a DeploymentDescriptor is similar to the one used for the Okapi-test-module.
Note that the launchDescriptor
dictionary is defined here.
$ cat > okapi-deploy-test-module-auth.json <<END
{
"srvcId": "test-auth-3.4.1",
"nodeId": "localhost",
"descriptor": {
"exec": "java -Dport=%p -jar okapi-test-auth-module/target/okapi-test-auth-module-fat.jar"
}
}
END
$ curl -i -w '\n' -X POST -H 'Content-type: application/json' \
-d @okapi-deploy-test-module-auth.json http://localhost:9130/_/discovery/modules
$ cat > okapi-enable-auth.json <<END
{
"id": "test-auth-3.4.1"
}
END
$ curl -i -w '\n' -X POST -H 'Content-type: application/json' \
-d @okapi-enable-auth.json http://localhost:9130/_/proxy/tenants/testlib/modules
If we now send the same test request from the end of the previous lesson to the Okapi-test-module, we see a different response from the Okapi Gateway.
$ curl -i -w '\n' -X GET -H 'X-Okapi-Tenant: testlib' http://localhost:9130/testb
HTTP/1.1 401 Unauthorized
Content-Type: text/plain
X-Okapi-Trace: GET test-auth-3.4.1 http://localhost:9132/testb : 401 62623us
Transfer-Encoding: chunked
Auth.check called without X-Okapi-Token
With the Okapi-test-auth-module filter now configured to intercept all requests to the Okapi Gateway, the Gateway responds with an HTTP 401 (“Unauthorized”) and in the response body tells us that the X-Okapi-Token is missing. This is the same X-Okapi-Token described in the first section of this lesson. If we send a request header with a valid X-Okapi-Token, the request is successful.
$ curl -i -w '\n' -X GET -H 'X-Okapi-Tenant: testlib' \
-H 'X-Okapi-Token: dummyJwt.eyJzdWIiOiJzZWIiLCJ0ZW5hbnQiOm51bGx9.sig' \
http://localhost:9130/testb
HTTP/1.1 200 OK
X-Okapi-Trace: GET test-auth-3.4.1 http://localhost:9132/testb : 202 152538us
Content-Type: text/plain
X-Okapi-Trace: GET test-basic-1.0.0 http://localhost:9131/testb : 200 7440us
Transfer-Encoding: chunked
It works