JWT

JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties. This Integration can be used to Generate New JWT Tokens, Encode and Decode Existing Ones.

Authentication & Identity Management · JWT Token Generator

Details

IDJWT
ProviderOpen Source
CategoryAuthentication & Identity Management
From Version5.5.0
Docker Imagedemisto/auth-utils:1.0.0.3562326
Supported ModulesAgentix XSIAM

README

JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties. This Integration can be used to Generate New JWT Tokens, Encode and Decode Existing Ones.
This integration was integrated and tested with generic JWT authentication service.

Configure JWT in Cortex

Parameter Description Required
Your server URL The authentication server URL True
Secret Key The secret key to sign the authentication token. True
Issuer Claim The “iss” (issuer) claim identifies the principal that issued the JWT. False
Audience Claim The “aud” (audience) claim identifies the recipients that the JWT is intended for. False
Trust any certificate (not secure)   False
Use system proxy settings   False

Commands

You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.

jwt-generate-access-token


Generates a JWT authorization token with an optional scope and queries the API for an access token and then returns the received API access token

Base Command

jwt-generate-access-token

Input

Argument Name Description Required
jti The “jti” (JWT ID) claim provides a unique identifier for the JWT token. Optional
iss The “iss” (issuer) claim identifies the principal that issued the JWT. Optional
aud The “aud” (audience) claim identifies the recipients that the JWT is intended for. Optional
sub The “sub” (subject) claim identifies the principal that is the subject of the JWT. Optional
scp The “scp” (scope) claim is described in OAuth 2.0 Token Exchange as an array of strings, each of which represents an OAuth Scope granted for the issued security token. Optional
iat The “iat” (issued at) claim identifies the time at which the JWT was issued. Optional
exp The “exp” (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. Optional
nbf The “nbf” (not before) claim identifies the time before which the JWT MUST NOT be accepted for processing. Optional
additionalClaims Additional claims to include in the request. Optional
tokenTimeout Token Timeout in Seconds. Default is 300. Optional

Context Output

Path Type Description
JWT.Token.ID String The JWT Token ID
JWT.Token.AccessToken String The JWT Access Token Value
JWT.Token.AuthenticationToken String JWT Authentication Token

Command Example

!jwt-generate-access-token iss="http://example.com" sub="3233-2344-4b52-2323-fc0bfb11e673" additionalClaims="{"parameter1":"23323-323-4854-893c-b59610423ad"}" tokenTimeout="300"

Context Example

{
    "JWT": {
        "Token": {
            "AccessToken": "***",
            "AuthenticationToken": "***",
            "ID": "009eb036-1e60-43e5-aad2-1187462db0be"
        }
    }
}

Human Readable Output

Results

AccessToken AuthenticationToken ID
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MjIwNTA1ODMsImlhdCI6MTYyMjA1MDI4MywianRpIjoiMDA5ZWIwMzYtMWU2MC00M2U1LWFhZDItMTE4NzQ2MmRiMGJlIiwiaXNzIjoiaHR0cDovL2V4YW1wbGUuY29tIiwic3ViIjoiMzIzMy0yMzQ0LTRiNTItMjMyMy1mYzBiZmIxMWU2NzMiLCJwYXJhbWV0ZXIxIjoiMjMzMjMtMzIzLTQ4NTQtODkzYy1iNTk2MTA0MjNhZCJ9.13zCwNhvt8fCuyHBcmdbDSaXUIpDRI95Q5-m1EbPQmk”, 009eb036-1e60-43e5-aad2-1187462db0be  

jwt-generate-authentication-payload


Generates a JWT authorization request payload by encoding the provided claims.

Base Command

jwt-generate-authentication-payload

Input

Argument Name Description Required
jti The “jti” (JWT ID) claim provides a unique identifier for the JWT token. Optional
iss The “iss” (issuer) claim identifies the principal that issued the JWT. Optional
aud The “aud” (audience) claim identifies the recipients that the JWT is intended for. Optional
sub The “sub” (subject) claim identifies the principal that is the subject of the JWT. Optional
scp The “scp” (scope) claim is described in OAuth 2.0 Token Exchange as an array of strings, each of which represents an OAuth Scope granted for the issued security token. Optional
iat The “iat” (issued at) claim identifies the time at which the JWT was issued. Optional
exp The “exp” (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. . Optional
nbf The “nbf” (not before) claim identifies the time before which the JWT MUST NOT be accepted for processing. Optional
additionalClaims Additional claims to include in the request. Optional
tokenTimeout Token Timeout in Seconds. Default is 300. Optional

Context Output

Path Type Description
JWT.Token.ID String The JWT Token ID
JWT.Token.AuthenticationToken String The JWT Authentication Token Value

Command Example

!jwt-generate-authentication-payload iss="http://example.com" sub="3233-2344-4b52-2323-fc0bfb11e673" additionalClaims=`{"parameter1":"23323-323-4854-893c-b59610423ad"}`

Context Example

{
    "JWT": {
        "Token": {
            "AuthenticationToken": "***",
            "ID": "66175ceb-f910-4b32-8a53-739ecf37a95d"
        }
    }
}

Human Readable Output

Results

AuthenticationToken ID
***  

jwt-decode-token


A command to decode JWT tokens

Base Command

jwt-decode-token

Input

Argument Name Description Required
token The token to decode. Required
secret The secret to validate the token signature. Optional

Context Output

There is no context output for this command.

Command Example

!jwt-decode-token token="************************************.*********************************************************************************************************************************************************************************************************************************************************************.******************************************"

Context Example

{
    "JWT": {
        "DecodedToken": {
            "exp": 1622050583,
            "iat": 1622050283,
            "iss": "http://example.com",
            "jti": "009eb036-1e60-43e5-aad2-1187462db0be",
            "parameter1": "23323-323-4854-893c-b59610423ad",
            "sub": "3233-2344-4b52-2323-fc0bfb11e673"
        }
    }
}

Human Readable Output

Results

exp iat iss jti parameter1 sub
1622050583 1622050283 http://example.com 009eb036-1e60-43e5-aad2-1187462db0be 23323-323-4854-893c-b59610423ad 3233-2344-4b52-2323-fc0bfb11e673

Configuration parameters

  • url — Your server URL (required)
  • key — Secret Key (required)
  • algorithm — Algorithm
  • iss — Issuer
  • aud — Audience
  • jti — Token ID
  • sub — Subject
  • scp — Scope
  • iat — Issued At
  • exp — Expiration Time
  • nbf — Not Before
  • additionalClaims — Additional Claims
  • tokenTimeout — Token Timeout
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (3)

  • jwt-decode-token

    A command to decode JWT tokens

  • jwt-generate-access-token

    Generates a JWT authorization token with an optional scope and queries the API for an access token and then returns the received API access token

  • jwt-generate-authentication-payload

    Generates a JWT authorization request payload by encoding the provided claims.

import demistomock as demisto
from CommonServerPython import *  # noqa # pylint: disable=unused-wildcard-import
from CommonServerUserPython import *  # noqa

import traceback
import jwt
import uuid

# Disable insecure warnings
import urllib3

urllib3.disable_warnings()  # pylint: disable=no-member


""" CONSTANTS """

DATE_FORMAT = "%Y-%m-%dT%H:%M:%SZ"  # ISO8601 format with UTC, default in XSOAR

""" CLIENT CLASS """


class Client(BaseClient):
    def request_access_token(self, headers, body):
        response = self._http_request("post", headers=headers, json_data=body)
        return response


""" HELPER FUNCTIONS """


def encode_authentication_token(
    secret_key,
    jti=None,
    iss=None,
    aud=None,
    sub=None,
    scp=None,
    iat=None,
    exp=None,
    nbf=None,
    token_timeout=None,
    additional_claims=None,
    algorithm="HS256",
):
    token_id = str(uuid.uuid4())
    jti = jti or token_id

    token_timeout = token_timeout or "300"
    now = datetime.utcnow()
    timeout_datetime = now + timedelta(seconds=int(token_timeout))
    epoch_time = int((now - datetime(1970, 1, 1)).total_seconds())
    epoch_timeout = int((timeout_datetime - datetime(1970, 1, 1)).total_seconds())
    exp = exp or epoch_timeout
    iat = iat or epoch_time

    claims = {"exp": exp, "iat": iat, "jti": jti}

    if iss:
        claims["iss"] = iss
    if aud:
        claims["aud"] = aud
    if sub:
        claims["sub"] = sub
    if scp:
        claims["iss"] = scp
    if scp:
        claims["nbf"] = nbf
    if additional_claims:
        claims.update(json.loads(additional_claims))

    payload = jwt.encode(claims, secret_key, algorithm=algorithm)

    return jti, payload


""" COMMAND FUNCTIONS """


def test_module():
    return "ok"


def jwt_generate_authentication_payload_command(args, params):
    secret_key = params.get("key")
    jti = args.get("jti") or params.get("jti")
    iss = args.get("iss") or params.get("iss", params["url"])
    aud = args.get("aud") or params.get("aud")
    sub = args.get("sub") or params.get("sub")
    scp = args.get("scp") or params.get("scp")
    iat = args.get("iat") or params.get("iat")
    exp = args.get("exp") or params.get("exp")
    nbf = args.get("nbf") or params.get("nbf")
    algorithm = args.get("algorithm") or params.get("algorithm")
    additional_claims = args.get("additionalClaims") or params.get("additionalClaims")
    token_timeout = args.get("tokenTimeout") or params.get("tokenTimeout")

    jti, payload = encode_authentication_token(
        secret_key=secret_key,
        jti=jti,
        iss=iss,
        aud=aud,
        sub=sub,
        scp=scp,
        iat=iat,
        exp=exp,
        nbf=nbf,
        token_timeout=token_timeout,
        additional_claims=additional_claims,
        algorithm=algorithm,
    )
    result = {"ID": jti, "AuthenticationToken": payload}

    return CommandResults(
        outputs_prefix="JWT.Token",
        outputs_key_field="ID",
        outputs=result,
    )


def jwt_generate_access_token_command(client, args, params):
    secret_key = params.get("key")
    jti = args.get("jti") or params.get("jti")
    iss = args.get("iss") or params.get("iss", params["url"])
    aud = args.get("aud") or params.get("aud")
    sub = args.get("sub") or params.get("sub")
    scp = args.get("scp") or params.get("scp")
    iat = args.get("iat") or params.get("iat")
    exp = args.get("exp") or params.get("exp")
    nbf = args.get("nbf") or params.get("nbf")
    algorithm = args.get("algorithm") or params.get("algorithm")
    additional_claims = args.get("additionalClaims") or params.get("additionalClaims")
    token_timeout = args.get("tokenTimeout") or params.get("tokenTimeout")

    jti, payload = encode_authentication_token(
        secret_key=secret_key,
        jti=jti,
        iss=iss,
        aud=aud,
        sub=sub,
        scp=scp,
        iat=iat,
        exp=exp,
        nbf=nbf,
        token_timeout=token_timeout,
        additional_claims=additional_claims,
        algorithm=algorithm,
    )
    payload = {"auth_token": payload}
    headers = {"Content-Type": "application/json; charset=utf-8"}
    res = client.request_access_token(headers=headers, body=payload)
    access_token = res["access_token"]

    result = {"ID": jti, "AuthenticationToken": payload["auth_token"], "AccessToken": access_token}

    return CommandResults(
        outputs_prefix="JWT.Token",
        outputs_key_field="ID",
        outputs=result,
    )


def jwt_decode_token_command(args):
    token = args.get("token")
    secret = args.get("secret", "nosecret")
    result = jwt.decode(token, secret, algorithms=["HS256"], options={"verify_signature": False})
    return CommandResults(
        outputs_prefix="JWT.DecodedToken",
        outputs_key_field="ID",
        outputs=result,
    )


""" MAIN FUNCTION """


def main():
    base_url = demisto.params().get("url")

    verify_certificate = not demisto.params().get("insecure", False)
    proxy = demisto.params().get("proxy", False)

    demisto.debug(f"Command being called is {demisto.command()}")
    try:
        headers: dict = {}
        client = Client(base_url=base_url, verify=verify_certificate, headers=headers, proxy=proxy)
        if demisto.command() == "test-module":
            result = test_module()
            return_results(result)

        elif demisto.command() == "jwt-generate-authentication-payload":
            return_results(jwt_generate_authentication_payload_command(demisto.args(), demisto.params()))
        elif demisto.command() == "jwt-generate-access-token":
            return_results(jwt_generate_access_token_command(client, demisto.args(), demisto.params()))
        elif demisto.command() == "jwt-decode-token":
            return_results(jwt_decode_token_command(demisto.args()))

    # Log exceptions and return errors
    except Exception as e:
        demisto.error(traceback.format_exc())  # print the traceback
        return_error(f"Failed to execute {demisto.command()} command.\nError:\n{str(e)}")


""" ENTRY POINT """


if __name__ in ("__main__", "__builtin__", "builtins"):
    main()