Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

JSON Web Tokens 2 JWT

Slide 3

Slide 3 text

“jot” 3

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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]

Slide 6

Slide 6 text

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)

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

Turnkey Solution for Rapid IoT Deployment Kalay Platform

Slide 9

Slide 9 text

What is Kalay? 9

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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)

Slide 12

Slide 12 text

A server has to know who is requesting the resource 12

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

Server based authentication 14 user id/password

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

Token based authentication 16 user id/password Stateless

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

How usually JSON Web Tokens work ? 21

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

How to implement it in python ? 24

Slide 25

Slide 25 text

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']

Slide 26

Slide 26 text

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']

Slide 27

Slide 27 text

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/

Slide 28

Slide 28 text

We don’t need to reinvent the wheel 28

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

Example Scenarios 32

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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)

Slide 39

Slide 39 text

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/

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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:

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

Thank you! Questions? 45