Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Authentication with JSON Web Tokens

suci
June 04, 2016

Authentication with JSON Web Tokens

suci

June 04, 2016
Tweet

More Decks by suci

Other Decks in Programming

Transcript

  1. Authentication
    with
    JSON Web Tokens
    2016. 06. 04
    pyconTW
    Shuhsi Lin
    Data Engineer of Throughtek

    View Slide

  2. JSON Web Tokens
    2
    JWT

    View Slide

  3. “jot”
    3

    View Slide

  4. 1. Why we need authorization
    2. The idea of Authorization Server
    3. How to implement JWT
    - PyJWT
    - Django & Flask
    4
    Agenda

    View Slide

  5. About Me
    Data Engineer of Throughtek
    Currently working with
    - IoT -PaaS
    - Streaming processing framework
    - WebAPI
    - Lurking in PyHug, Taipei.py and various Meetups
    5
    Shuhsi Lin
    [email protected]
    [email protected]

    View Slide

  6. I A A
    Identity
    “Who are you?”
    6
    Authentication
    “OK, how can you prove it?”
    Authorization
    “What can you do?”
    Identity and Access Management (IAM)

    View Slide

  7. Copyright © 2016 ThroughTek Co., Ltd. All rights reserved. Confidential. Do not distribute. 7
    • Generic applications
    • Customization service
    • Kalay Kit
    • FW integration
    micro-service system

    View Slide

  8. Turnkey Solution for Rapid IoT Deployment
    Kalay Platform

    View Slide

  9. What is Kalay?
    9

    View Slide

  10. Copyright © 2016 ThroughTek Co., Ltd. All rights reserved. Confidential. Do not distribute. 10 10
    “Handshake” in the language
    of the aboriginal Tao people of Taiwan
    Connecting All Devices

    View Slide

  11. Copyright © 2016 ThroughTek Co., Ltd. All rights reserved. Confidential. Do not distribute. 11
    User Account
    • Define multiple user types
    • Manage and control user permission
    • Monitor login status and activity
    UID & Device
    • Real time log analysis
    • Track connection status, IP, region
    • Monitor and backup log data
    Why we need Identity Management
    (Device and User Account)

    View Slide

  12. A server has to know
    who is requesting the resource
    12

    View Slide

  13. How has authentication been done in web?
    13
    ● Server based
    ● Token based

    View Slide

  14. Server based authentication
    14
    user id/password

    View Slide

  15. Problems from Server based authentication
    ● Sessions
    ● Scalability
    ● Cross-Origin Resource Sharing (CORS)
    ● Cross-Site Request Forgery (CSRF)
    15

    View Slide

  16. Token based authentication
    16
    user id/password
    Stateless

    View Slide

  17. Token based authentication
    ● Stateless and scalable servers
    ● Mobile application ready
    ● Pass authentication to other applications
    ● Extra security
    17

    View Slide

  18. 18
    https://jwt.io/
    2,506 6,120
    https://github.com/search?q=jwt
    http://stackoverflow.com/search?q=jwt
    ● Compact and Self-contained
    ● Across different programming languages
    ● Passed around easily

    View Slide

  19. JWT looks like?
    19
    Three strings separated by “.”
    aaaaaaaaa.bbbbbbbbb.ccccccccccc
    header payload signature

    View Slide

  20. 20
    https://jwt.io/#debugger-io
    don’t put sensitive data here

    View Slide

  21. How usually JSON Web Tokens work ?
    21

    View Slide

  22. How usually JSON Web Tokens work ?
    22
    POST login/
    user id/password
    https://auth0.com/learn/json-web-tokens/
    return JWT token
    request with Header
    Authorization: Bearer
    create JWT
    Check JWT
    send responses

    View Slide

  23. What do we put in payload
    ● Reserved : predefined claim
    ● iss (issuer), exp (expiration time), sub (subject), aud (audience)
    ● and etc.
    ● Public:
    ● name, email, email_verified, and etc.
    ● http://www.iana.org/assignments/jwt/jwt.xhtml
    ● Private : custom claims
    23

    View Slide

  24. How to implement it in
    python ?
    24

    View Slide

  25. 25
    In [1]: import json
    In [2]: import hmac
    In [3]: from hashlib import sha256
    In [4]: from base64 import urlsafe_b64encode
    In [5]: segments =[]
    In [6]: header_dict = {
    ...: 'typ': 'JWT',
    ...: 'alg': 'HS256'
    ...: }
    In [7]: json_header = json.dumps(header_dict).encode('utf-8')
    In [8]: header = urlsafe_b64encode(json_header)
    In [9]: segments.append(header)
    In [10]: segments
    Out[10]: [b'eyJ0eXAiOiAiSldUIiwgImFsZyI6ICJIUzI1NiJ9']

    View Slide

  26. 26
    In [11]: payload_dict = {
    ....: 'user_id':'pythontw2016'
    ....: }
    In [12]: json_payload =json.dumps(payload_dict).encode('utf-8')
    In [13]: payload = urlsafe_b64encode(json_payload)
    In [14]: segments.append(payload)
    In [15]: segments
    Out[15]:
    [b'eyJ0eXAiOiAiSldUIiwgImFsZyI6ICJIUzI1NiJ9',
    b'eyJ1c2VyX2lkIjogInB5dGhvbnR3MjAxNiJ9']

    View Slide

  27. 27
    In [16]: SECRET = b'secret'
    In [17]: signing_input = b'.'.join(segments)
    In [18]: sig = hmac.new (SECRET, signing_input, sha256)
    In [19]: signature = urlsafe_b64encode(sig.digest())
    In [20]: segments.append(signature)
    In [21]: segments
    Out[21]:
    [b'eyJ0eXAiOiAiSldUIiwgImFsZyI6ICJIUzI1NiJ9',
    b'eyJ1c2VyX2lkIjogInB5dGhvbnR3MjAxNiJ9',
    b'qhevGfl16LBHjRG2wb6xDitbGt3lDK-2iUYCsLseCJY=']
    In [22]: token = b'.'.join(segments)
    In [23]: token
    Out[23]:
    b'eyJ0eXAiOiAiSldUIiwgImFsZyI6ICJIUzI1NiJ9.eyJ1c2VyX2lkIjogInB5dGhvbnR3MjAx
    NiJ9.qhevGfl16LBHjRG2wb6xDitbGt3lDK-2iUYCsLseCJY='
    Test this token in https://jwt.io/

    View Slide

  28. We don’t need to
    reinvent the
    wheel
    28

    View Slide

  29. 29
    https://jwt.io/#libraries-io
    PyJWT

    View Slide

  30. 30
    PyJWT
    Django DRF JWT Auth
    json
    hmac
    base64
    hashlib
    Flask-JWT

    View Slide

  31. PyJWT
    >>> import jwt
    >>> jwt_token = jwt.encode({ 'payload': ‘pycontw 2106’ }, 'secret',
    algorithm='HS256')
    'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXlsb2FkIjoicHljb250dyAyMDE2In
    0.TRRENrqd8lc3_AQeo3IRheVkZpMkcqXqYQi891pFL6w’
    >>> jwt.decode(jwt_token, 'secret', algorithms=[ 'HS256'])
    {'payload': 'pycontw 2016'}
    31
    https://github.com/jpadilla/pyjwt
    pip install PyJWT
    see more in Registered Claim Names

    View Slide

  32. Example Scenarios
    32

    View Slide

  33. Copyright © 2016 ThroughTek Co., Ltd. All rights reserved. Confidential. Do not distribute. 33
    • Generic applications
    • Customization service
    • Kalay Kit
    • FW integration
    micro-service system

    View Slide

  34. Kalay
    services
    Users
    Kalay AM Kalay DM
    JWT
    login
    Kalay DC
    mqtt/https
    shared keys shared keys
    shared keys
    Kalay Cloud
    Kalay
    services
    Kalay
    services
    devices
    actions
    (bind/view/control….)
    with JWT

    View Slide

  35. Messaging API for Mobile Apps and Websites
    ● http://api.diuit.com/

    View Slide

  36. Authentication with JWT for security purpose
    1. User sends login request with credential
    2. Auth user on your server (account server)
    3. Request for Nonce on Diuit server
    4. Obtain nonce from Diuit server
    5. Use JWT to request session token
    6. Obtain session token from Diuit server
    7. Send session token back to messaging client
    8. Authenticate messaging client on Diuit server using
    "loginWithAuthToken"
    JWT
    Your own account server
    user login
    nonce
    =>create JWT
    { "typ": "JWT", "alg": "RS256" "cty": "diuit-eit;v=1"
    "kid": ${EncryptionKeyId} }
    header
    { "iss": ${DIUIT_APP_ID}
    "sub": ${UNIQUE_USER_ID}
    "iat": ${CURRENT_TIME_IN_ISO8601_FORMAT}
    "exp":${SESSION_EXPIRATION_TIME_IN_ISO8601_FORMAT}
    "nce": ${AUTHENTICATION_NONCE} }
    payload

    View Slide

  37. Django REST framework JWT
    JSON Web Token Authentication support for Django REST Framework
    37

    View Slide

  38. Django DRF JWT
    38
    https://github.com/GetBlimp/django-rest-framework-jwt
    Steps:
    ● pip install djangorestframework-jwt
    ● add JSONWebTokenAuthentication in Django REST framework's
    DEFAULT_AUTHENTICATION_CLASSES (settings.py)
    ● add URL routes (urls.py)
    ○ provide JWT token (obtain_jwt_token)
    ○ refresh token (refresh_jwt_token)
    ○ verify token (verify_jwt_token)
    ● additional settings
    Requirements
    ● Python (2.7, 3.3, 3.4)
    ● Django (1.8, 1.9)
    ● Django REST Framework (3.0, 3.1, 3.2, 3.3)

    View Slide

  39. settings.py
    39
    REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
    'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
    'rest_framework.authentication.SessionAuthentication',
    'rest_framework.authentication.BasicAuthentication',
    'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    ),
    }
    from rest_framework_jwt.views import obtain_jwt_token
    #...
    urlpatterns = patterns(
    '',
    # ...
    url(r'^api-token-auth/', obtain_jwt_token),
    url(r'^api-token-refresh/', refresh_jwt_token),
    url(r'^api-token-verify/', verify_jwt_token),
    )
    urls.py
    http://getblimp.github.io/django-rest-framework-jwt/

    View Slide

  40. Flask-JWT
    Add basic JWT features to your Flask application
    40
    https://pythonhosted.org/Flask-JWT/

    View Slide

  41. Flask-JWT
    from flask import Flask
    from flask_jwt import JWT, jwt_required, current_identity
    from werkzeug.security import safe_str_cmp
    41
    https://pythonhosted.org/Flask-JWT/
    pip install Flask-JWT
    class User(object):
    def __init__(self, id, username, password):
    self.id = id
    self.username = username
    self.password = password
    def __str__(self):
    return "User(id='%s')" % self.id
    users = [
    User(1, 'user1', 'abcxyz'),
    User(2, 'user2', 'abcxyz'),
    ]
    username_table = {u.username: u for u in users}
    userid_table = {u.id: u for u in users}
    Minimum viable application configuration:

    View Slide

  42. 42
    app = Flask(__name__)
    app.debug = True
    app.config['SECRET_KEY'] = ' super-secret'
    jwt = JWT(app, authenticate, identity )
    def identity(payload):
    user_id = payload['identity']
    return userid_table.get(user_id,
    None)
    def authenticate(username, password):
    user = username_table.get(username, None)
    if user and safe_str_cmp(user.password.encode('utf-8'), password.encode('utf-8')):
    return user
    @app.route('/protected')
    @jwt_required()
    def protected():
    return '%s' % current_identity
    if __name__ == '__main__':
    app.run()
    Configuration
    JWT_AUTH_URL_RULE:
    The authentication endpoint URL.
    Defaults to /auth
    https://pythonhosted.org/Flask-JWT/
    jwt working

    View Slide

  43. Recap
    ● JWT (‘jot’) : header, payload, signature
    ● Stateless token-based authentication
    ● Use libraries
    ● PyJWT, Django DRF JWT , Flask-JWT
    ● Provide, refresh, verify JWT
    43

    View Slide

  44. About JWT
    Ref:
    ● JWT
    ● https://jwt.io/
    ● https://auth0.com/learn/json-web-tokens/
    ● https://self-issued.info/docs/draft-ietf-oauth-json-web-token.html
    ● PyJWT (https://pyjwt.readthedocs.org/)
    ● django-rest-framework-jwt (http://getblimp.github.io/django-rest-framework-jwt/)
    ● Flask-JWT (https://pythonhosted.org/Flask-JWT/)
    ● DjangoCon US 2014 talk on JWT https://speakerdeck.com/jpadilla/djangocon-json-web-tokens
    ● JWT in Auth0 https://auth0.com/blog/2014/12/02/using-json-web-tokens-as-api-keys/
    About Authentication
    ● https://www.owasp.org/index.php/Authentication_Cheat_Sheet
    and others:
    ● Kalay platform (http://www.throughtek.com.tw/kalay_overview.html)
    ● diuit messaging api (http://api.diuit.com/ , https://github.com/diuitAPI)
    ● icons: (https://thenounproject.com/)
    44

    View Slide

  45. Thank you!
    Questions?
    45

    View Slide