This package experiments with an extended Nirum HTTP transport which authorizes clients using JOSE (JSON Object Signing and Encryption). It proposes a new extension of the existing Nirum HTTP transport and also provides its minimum implementation in Python.
It purposes to authorizes a client, not a server. In this scheme, a client assumes a server is trustworthy; this kind of trust is usually made through a domain name and HTTPS.
An alternative to this scheme is TLS client authentication. It's more standard-ish way (which means more portable) to authorize a client. As it is a TLS-level solution, the vanilla Nirum HTTP transport is agnostic to it. However, if a node dealing with TLS thing does not support TLS client authentication, it is difficult to adapt. For example, if your server itself exposes only an HTTP and an L7 in front of that proxies its upstream HTTP to the public HTTPS, the L7 should support TLS client as well.
On the other hand, this JOSE-based scheme works well with any kind of L4, L7,
or HTTP(S) proxies. Signing and verification is done upon an application layer.
On the HTTP(S) level, it is just substituting Content-Type
from
application/json
to application/jose
.
A client code need to use the nirum_jose.client.SigningHttpTransport
class.
Its constructor is mostly compatible with nirum_http.HttpTransport
except
it also takes a shared secret and an algorithm name to use:
from nirum_jose.client import SigningHttpTransport
from your_schema import YourService
transport = SigningHttpTransport(
'https://example.com/',
'secret key',
algorithm='HS256'
)
client = YourService.Client(transport)
A server code need to use the nirum_jose.server.SigningWsgiApp
instead of
nirum_wsgi.WsgiApp
. Its constructor takes a service instance and a shared
secret, again. (Note that it does not take allowed_origins
or
allowed_headers
; Configuring CORS is unsupported.)
from nirum_jose.server import SigningWsgiApp
from your_app import YourServiceImpl
service = YourServiceImpl()
app = SigningWsgiApp(service, 'secret key')
Since it is still experimental, it lacks features and has several limits when it's compared to the vanilla HTTP transport:
- Python 3.6 or higher is required.
- Service interfaces generated by older versions of the compiler than Nirum 0.4.0 are unsupported.
- A server currently can have only one secret key. This means all clients to a server need to share a single secret key together. It's also why we explain it authorizes clients, not authenticates.
- REST-style URI routes are unsupported; all
@http-resource
annotations are ignored. - CORS configuration is unsupported.
- As it is no more vanilla JSON, it is hard to make a request for debug purpose
using tools like
curl
.