- Add JWT token plugin feature. Added patches: u_added_jwt_tokens_capability.patch PyJWT-token-plugin.patch: fate#325762 OBS-URL: https://build.opensuse.org/request/show/674430 OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-websockify?expand=0&rev=33
72 lines
2.7 KiB
Diff
72 lines
2.7 KiB
Diff
From 6dc9005930798873ffa714d184312aafd0209503 Mon Sep 17 00:00:00 2001
|
|
From: UXabre <arend.lapere@gmail.com>
|
|
Date: Thu, 17 Jan 2019 08:53:01 -0500
|
|
Subject: [PATCH] Added JWT/JWS/JWE tokens capability
|
|
|
|
---
|
|
test-requirements.txt | 1 +
|
|
tests/fixtures/private.pem | 27 +++++++++++
|
|
tests/fixtures/public.pem | 9 ++++
|
|
tests/fixtures/symmetric.key | 1 +
|
|
tests/test_websocketproxy.py | 90 ++++++++++++++++++++++++++++++++++++
|
|
websockify/token_plugins.py | 46 ++++++++++++++++++
|
|
6 files changed, 174 insertions(+)
|
|
create mode 100644 tests/fixtures/private.pem
|
|
create mode 100644 tests/fixtures/public.pem
|
|
create mode 100644 tests/fixtures/symmetric.key
|
|
|
|
diff --git a/websockify/token_plugins.py b/websockify/token_plugins.py
|
|
index e87dcd0..45e974c 100644
|
|
--- a/websockify/token_plugins.py
|
|
+++ b/websockify/token_plugins.py
|
|
@@ -87,3 +87,49 @@ class JSONTokenApi(BaseTokenAPI):
|
|
def process_result(self, resp):
|
|
resp_json = resp.json()
|
|
return (resp_json['host'], resp_json['port'])
|
|
+
|
|
+
|
|
+class JWTTokenApi(BasePlugin):
|
|
+ # source is a JWT-token, with hostname and port included
|
|
+ # Both JWS as JWE tokens are accepted. With regards to JWE tokens, the key is re-used for both validation and decryption.
|
|
+
|
|
+ def lookup(self, token):
|
|
+ try:
|
|
+ from jwcrypto import jwt
|
|
+ import json
|
|
+
|
|
+ key = jwt.JWK()
|
|
+
|
|
+ try:
|
|
+ with open(self.source, 'rb') as key_file:
|
|
+ key_data = key_file.read()
|
|
+ except Exception as e:
|
|
+ print >>sys.stderr, "Error loading key file: %s" % (e)
|
|
+ return None
|
|
+
|
|
+ try:
|
|
+ key.import_from_pem(key_data)
|
|
+ except:
|
|
+ try:
|
|
+ key.import_key(k=key_data,kty='oct')
|
|
+ except:
|
|
+ print >>sys.stderr, 'Failed to correctly parse key data!'
|
|
+ return None
|
|
+
|
|
+ try:
|
|
+ token = jwt.JWT(key=key, jwt=token)
|
|
+ parsed_header = json.loads(token.header)
|
|
+
|
|
+ if 'enc' in parsed_header:
|
|
+ # Token is encrypted, so we need to decrypt by passing the claims to a new instance
|
|
+ token = jwt.JWT(key=key, jwt=token.claims)
|
|
+
|
|
+ parsed = json.loads(token.claims)
|
|
+
|
|
+ return (parsed['host'], parsed['port'])
|
|
+ except Exception as e:
|
|
+ print >>sys.stderr, "Failed to parse token: %s" % (e)
|
|
+ return None
|
|
+ except ImportError as e:
|
|
+ print >>sys.stderr, "package jwcrypto not found, are you sure you've installed it correctly?"
|
|
+ return None
|