Browse Source

[jwt] Add issuer and audience for token verification (#2505)

Ying Chen 4 years ago
parent
commit
218575add8

+ 6 - 0
desktop/conf.dist/hue.ini

@@ -438,6 +438,12 @@ idle_session_timeout=-1
 # Endpoint to fetch the public key from verification server.
 ## key_server_url=https://ext_authz:8000
 
+# The identifier of the service issued the JWT
+## issuer=None
+
+# The identifier of the resource intend to access
+## audience=None
+
 # Verify custom JWT signature.
 ## verify=true
 

+ 6 - 0
desktop/conf/pseudo-distributed.ini.tmpl

@@ -443,6 +443,12 @@
       # Endpoint to fetch the public key from verification server.
       ## key_server_url=https://ext_authz:8000
 
+      # The identifier of the service issued the JWT
+      ## issuer=None
+
+      # The identifier of the resource intend to access
+      ## audience=None
+
       # Verify custom JWT signature.
       ## verify=true
 

+ 11 - 0
desktop/core/src/desktop/auth/api_authentications.py

@@ -60,14 +60,25 @@ class JwtAuthentication(authentication.BaseAuthentication):
       payload = jwt.decode(
         access_token,
         public_key_pem,
+        issuer=AUTH.JWT.ISSUER.get(),
+        audience=AUTH.JWT.AUDIENCE.get(),
         algorithms=["RS256"],
         verify=AUTH.JWT.VERIFY.get()
       )
     except jwt.DecodeError:
+      LOG.error('JwtAuthentication: Invalid token')
       raise exceptions.AuthenticationFailed('JwtAuthentication: Invalid token')
     except jwt.ExpiredSignatureError:
+      LOG.error('JwtAuthentication: Token expired')
       raise exceptions.AuthenticationFailed('JwtAuthentication: Token expired')
+    except jwt.InvalidIssuerError:
+      LOG.error('JwtAuthentication: issuer not match')
+      raise exceptions.AuthenticationFailed('JwtAuthentication: issuer not matching')
+    except jwt.InvalidAudienceError:
+      LOG.error('JwtAuthentication: audience not match or no audience')
+      raise exceptions.AuthenticationFailed('JwtAuthentication: audience not matching or no audience')
     except Exception as e:
+      LOG.error('JwtAuthentication: %s' % str(e))
       raise exceptions.AuthenticationFailed(e)
     
     if payload.get('user') is None:

+ 5 - 1
desktop/core/src/desktop/auth/api_authentications_tests.py

@@ -177,7 +177,9 @@ class TestJwtAuthentication():
 
         resets = [
           AUTH.JWT.VERIFY.set_for_testing(True),
-          AUTH.JWT.KEY_SERVER_URL.set_for_testing('https://ext-authz:8000')
+          AUTH.JWT.KEY_SERVER_URL.set_for_testing('https://ext-authz:8000'),
+          AUTH.JWT.ISSUER.set_for_testing('issuer'),
+          AUTH.JWT.AUDIENCE.set_for_testing('audience')
         ]
 
         try:
@@ -194,6 +196,8 @@ class TestJwtAuthentication():
             b'Vno2e527clXzQisfJKwb4hjfKRMhHfnYfyJxaoHqWfx8DjXmH3CMqlWr/+hL3y1+\n'
             b'4QIDAQAB\n'
             b'-----END PUBLIC KEY-----\n',
+            issuer=AUTH.JWT.ISSUER.get(),
+            audience=AUTH.JWT.AUDIENCE.get(),
             algorithms=['RS256'],
             verify=True
           )

+ 14 - 1
desktop/core/src/desktop/conf.py

@@ -1089,7 +1089,8 @@ AUTH = ConfigSection(
                   help=_("The service to use when querying PAM. "
                          "The service usually corresponds to a single filename in /etc/pam.d")),
     PAM_USE_PWD_MODULE=Config("pam_use_pwd_module",
-                       help=_("To use Python unix pwd module to get the username from the entered credentials in hue if Centrify like PAM service is in use. "
+                       help=_("To use Python unix pwd module to get the username from the entered credentials in hue"
+                              " if Centrify like PAM service is in use. "
                               "This will set the username to what is being returned by the pwd module."),
                        type=coerce_bool,
                        default=False),
@@ -1216,6 +1217,18 @@ AUTH = ConfigSection(
             type=str,
             help=_("Endpoint to fetch the public key from verification server.")
         ),
+        ISSUER=Config(
+          key="issuer",
+          default=None,
+          type=str,
+          help=_("The identifier of the service issued the JWT")
+        ),
+        AUDIENCE=Config(
+          key="audience",
+          default=None,
+          type=str,
+          help=_("The identifier of the resource intend to access")
+        ),
         VERIFY=Config(
             key="verify",
             default=True,