Welcome to the new Box Support website. Check out all the details here on what’s changed.

JWT claims

New post

Comments

5 comments

  • rocks

    Hi ,

     

    Please check out the JWT page on Box Developer Site: https://docs.box.com/docs/app-auth#section-5-constructing-the-claims

     

    The "exp" parameter is expecting a Epoch / Unix time value such as 1468262189 at the time of writing.

    Check out this time converter or use python to get the exact time right now.

     

     

    >>> import time
    >>> time.time()
    1468262189.884993

    Constructing a JWT Claim.png

     

    Below is an example python script which will help you get started with generating JWT assertions.  You will first need to install a couple of libraries (pyjwt and cryptography) - Check out https://jwt.io/ for this and other library options.

     

     

    procks@box:~/VENV$ virtualenv jwt  ##Optional - create a python Virtual Environment
    New python executable in jwt/bin/python
    Installing setuptools, pip, wheel...done.
    procks@box:~/VENV$ source jwt/bin/activate  ##Activate Virtual Environment
    (jwt)procks@box:~/VENV$ pip install --upgrade pip  ##Get latest pip
    Collecting pip
      .......
    Successfully installed pip-8.1.2
    (jwt)procks@box:~/VENV$ pip install cryptography ##To load JWT private key in next step
    Collecting cryptography
      .......
    Successfully installed cffi-1.7.0 cryptography-1.4 enum34-1.1.6 idna-2.1 ipaddress-1.0.16 pyasn1-0.1.9 pycparser-2.14 six-1.10.0
    (jwt)procks@box:~/VENV$ pip install pyjwt  ##To encode assertion in next step
    Collecting pyjwt
      Downloading PyJWT-1.4.0-py2.py3-none-any.whl
    Installing collected packages: pyjwt
    Successfully installed pyjwt-1.4.0
    (jwt)procks@box:~/VENV$ 

     

    Update the following script with the location of your Private key, Client ID and password.

     

     

    import jwt
    import uuid
    import datetime
    from cryptography.hazmat.backends import default_backend
    from cryptography.hazmat.primitives.asymmetric import dsa, rsa
    from cryptography.hazmat.primitives.serialization import load_pem_private_key
    # Loads the private key
    # Change the path to the path to your private key
    # Change the password to the password you used when generating the private key
    key = load_pem_private_key(open('/Users/procks/Box Sync/Coding/private_key.pem').read(), password="YOUR_PRIVATE_KEY_PW", backend=default_backend())
    
    print '\n####################################################################'
    print '#                         Building JWT Assertion                   #'
    print '####################################################################'
    
    client_id = "YOUR_CLIENT_ID" # (find out from https://app.box.com/developers/services)
    aud = "https://api.box.com/oauth2/token"
    iat = int(((datetime.datetime.utcnow() - datetime.datetime(1970,1,1)).total_seconds())+0)
    iat_time = datetime.datetime.fromtimestamp(iat).strftime('%c')
    exp = int(((datetime.datetime.utcnow() - datetime.datetime(1970,1,1)).total_seconds())+60)
    exp_time = datetime.datetime.fromtimestamp(exp).strftime('%c')
    # Generates a random hex for the jti
    jti = (uuid.uuid4()).hex
    
    print "Application Client ID (issuer): " + str(client_id)
    print "JWT Audience: " + str(aud)
    print "JWT Issued at Time (UNIX Epoch): " + str(iat)
    print "JWT Issued at Time: " + str(iat_time)
    print "Expiry Time for JWT (UNIX Epoch): " + str(exp)
    print "Expiry Time for JWT: " + str(exp_time) print "jti unique identifier: " + str(jti) print '####################################################################' + "\n" # Creates an assertion for an enterprise token # Change the iss to your client id # Change the sub to your enterprise id enterprise_assertion = jwt.encode({"iss": client_id,"sub": "YOUR_TENANT_ENTERPRISE_ID","box_sub_type": "enterprise","aud": aud,"jti": jti,"exp": exp,}, key, algorithm='RS256', headers={"alg": "RS256","typ": "JWT"}) print "Below is your JWT Assertion in the base64URLencoded format
    ......" + "\n" print enterprise_assertion # Creates an assertion for a user token # Change the iss to your client id # Change the sub to your user id
    #user_assertion = jwt.encode({"iss": "p0271k1w3vtdf1nk660cfhrx204qotfg","sub": "USER_ID_HERE","box_sub_type": "user","aud": aud,"jti": jti,"exp": exp, "iat": iat}, key, algorithm='RS256', headers={"alg": "RS256","typ": "JWT"}) #print user_assertion

     

    Your Terminal Output should look similar to below:

     

     

    (jwt)procks@box:~/Box Sync/Coding/Python$ python jwt-builder.py 
    
    ####################################################################
    #                         Building JWT Assertion                   #
    ####################################################################
    Application Client ID (issuer): MY_CLIENT_ID
    JWT Audience: https://api.box.com/oauth2/token
    JWT Issued at Time (UNIX Epoch): 1468261926
    JWT Issued at Time: Mon Jul 11 19:32:06 2016
    Expiry Time for JWT (UNIX Epoch): 1468261986
    Expiry Time for JWT: Mon Jul 11 19:33:06 2016
    jti unique identifier: e29c30cacfc24664a9ed4c5007451cab
    ####################################################################
    
    Below is your JWT Assertion in the base64URLencoded format 
    ...... eyJhbGciOiJSUNiIsInR5cCI6IXVCJ9.eyJzdWIiOiI0NjM0MTYiLCJpc3MiOiJwMDI3MWsxdzN2dGRmMW5rNjYwY2ZocngyMDRxb3RmZyIsImp0aSI6ImUyOWMzMGNhY2ZjMjQ2NjRhOWVkNGM1MDA3NDUxY2FiIiwiZXhwIjoxNDY4MjYxOTg2LCJib3hfc3ViX3R5cGUiOiJlbnRlcnBlIiwiYXVkIjoiaHR0cHM6Ly9hcGkuYm94LmNvbS9vYXvdG9rZW4ifQ.NVY5XHidst-sjWJ3RThCp9w-UB2RcqEqMQtlz-19QXAYVHIONw5Axw9YR7Kr1nHCckbYNtWxjiFe62qlxewNp4_2eOhcj_24uTzDdmwm9pM5eAegh_WHPh2PQP1WStr8c7owMxztQuPXvEiIH2VS7zrlVPG2Gg-NVbr7VcLCSf6ZaoTZcgfh04CeNS_PBzUbqOGVrEeFnoK5T84nrB71jFkEKAEexeVs3Pca0OhmPZ1zCS9TZ1-5ovgoraC_YYfKasCmIxavNceCpSgHjvMzh_MQQEGSE36sZE6Mp2p0YjgDtHXC64ZUTsG7nBskYYcwCdGGxU9QZmuJzw

     

     

    0
    Comment actions Permalink
  • jmoldow_box

    For those using Python, I highly recommend using our Box Python SDK: http://pypi.python.org/pypi/boxsdk , https://github.com/box/box-python-sdk . The JWTAuth class takes care of all of these details for you. All you need to do is provide the required information in the constructor and the authenticate methods.

     

    If you're using a different language, our other SDKs also support JWT auth for app users: https://docs.box.com/page/sdks

    0
    Comment actions Permalink
  • jwpully

    I am trying to use the boxsdk with jwt and I am following an example I found.  I keep getting this error...

     

    jwt.exceptions.InvalidTokenError: Key ID header parameter must be a string

     

    from boxsdk import JWTAuth, Client
    from settings import BoxCredentials

    boxcreds = BoxCredentials()

    def store_tokens(access_token, refresh_token):
    print access_token
    print refresh_token

    auth = JWTAuth(
    client_id=boxcreds.client_id,
    client_secret=boxcreds.client_secret,
    enterprise_id=boxcreds.enterprise_id,
    jwt_key_id=boxcreds.jwt_key_id,
    rsa_private_key_file_sys_path=boxcreds.rsa_private_key_file_sys_path,
    store_tokens=store_tokens,
    )

    access_token = auth.authenticate_instance()

    print access_token

    client = Client(auth)

     

    Suggestions?

    0
    Comment actions Permalink
  • kp_response

    Hi there. I am getting "invalid grant ... Please check the 'exp' claim."

    No matter what I use.... even when copied directly from http://www.epochconverter.com/ -  the link suggested in this thread. I even added the milliseconds.

     

    Example

    ***number removed for privacy***4.884993
    2/11/20***phone number removed for privacy***:53:04 AM

     

    Can someone tell me the issue? Thanks!

    0
    Comment actions Permalink
  • kp_response

    figured this out... the request was formatting the value as a string vs time. Now I am stuck at a different point

    0
    Comment actions Permalink

Please sign in to leave a comment.