2016 pycontw web api authentication

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

Upload: micron-technology

Post on 15-Apr-2017

1.257 views

Category:

Engineering


3 download

TRANSCRIPT

Page 1: 2016 pycontw web api authentication

Authentication

with JSON Web Tokens

2016. 06. 04 pyconTW

Shuhsi Lin

Data Engineer of Throughtek

Page 2: 2016 pycontw web api authentication

JSON Web Tokens

2

JWT

Page 3: 2016 pycontw web api authentication

“jot”

3

Page 4: 2016 pycontw web api authentication

1. Why we need authorization

2. The idea of Authorization Server

3. How to implement JWT

- PyJWT

- Django & Flask

4

Agenda

Page 5: 2016 pycontw web api authentication

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 [email protected]

[email protected]

Page 6: 2016 pycontw web api authentication

I A AIdentity “Who are you?”

6

Authentication“OK, how can you prove it?”

Authorization“What can you do?”

Identity and Access Management (IAM)

Page 7: 2016 pycontw web api authentication

Copyright © 2016 ThroughTek Co., Ltd. All rights reserved. Confidential. Do not distribute. 7

• Generic applications

• Customization service

• Kalay Kit

• FW integration

micro-service system

Page 8: 2016 pycontw web api authentication

Turnkey Solution for Rapid IoT DeploymentKalay Platform

Page 9: 2016 pycontw web api authentication

What is Kalay?

9

Page 10: 2016 pycontw web api authentication

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

Page 11: 2016 pycontw web api authentication

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)

Page 12: 2016 pycontw web api authentication

A server has to know

who is requesting the resource

12

Page 13: 2016 pycontw web api authentication

How has authentication been done in web?

13

● Server based● Token based

Page 14: 2016 pycontw web api authentication

Server based authentication

14

user id/password

Page 15: 2016 pycontw web api authentication

Problems from Server based authentication

● Sessions

● Scalability

● Cross-Origin Resource Sharing (CORS)

● Cross-Site Request Forgery (CSRF)

15

Page 16: 2016 pycontw web api authentication

Token based authentication

16

user id/password

Stateless

Page 17: 2016 pycontw web api authentication

Token based authentication

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

17

Page 18: 2016 pycontw web api authentication

18

https://jwt.io/

2,506 6,120

https://github.com/search?q=jwthttp://stackoverflow.com/search?q=jwt

● Compact and Self-contained

● Across different programming languages

● Passed around easily

Page 19: 2016 pycontw web api authentication

JWT looks like?

19

Three strings separated by “.”

aaaaaaaaa.bbbbbbbbb.cccccccccccheader payload signature

Page 20: 2016 pycontw web api authentication

20

https://jwt.io/#debugger-io

don’t put sensitive data here

Page 21: 2016 pycontw web api authentication

How usually JSON Web Tokens work ?

21

Page 22: 2016 pycontw web api authentication

How usually JSON Web Tokens work ?

22

POST login/user id/password

https://auth0.com/learn/json-web-tokens/

return JWT token

request with HeaderAuthorization: Bearer <json web token>

create JWT

Check JWTsend responses

Page 23: 2016 pycontw web api authentication

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

Page 24: 2016 pycontw web api authentication

How to implement it in python ?

24

Page 25: 2016 pycontw web api authentication

25

In [1]: import jsonIn [2]: import hmacIn [3]: from hashlib import sha256In [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]: segmentsOut[10]: [b'eyJ0eXAiOiAiSldUIiwgImFsZyI6ICJIUzI1NiJ9']

Page 26: 2016 pycontw web api authentication

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]: segmentsOut[15]:[b'eyJ0eXAiOiAiSldUIiwgImFsZyI6ICJIUzI1NiJ9', b'eyJ1c2VyX2lkIjogInB5dGhvbnR3MjAxNiJ9']

Page 27: 2016 pycontw web api authentication

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]: segmentsOut[21]:[b'eyJ0eXAiOiAiSldUIiwgImFsZyI6ICJIUzI1NiJ9', b'eyJ1c2VyX2lkIjogInB5dGhvbnR3MjAxNiJ9', b'qhevGfl16LBHjRG2wb6xDitbGt3lDK-2iUYCsLseCJY=']

In [22]: token = b'.'.join(segments)

In [23]: tokenOut[23]: b'eyJ0eXAiOiAiSldUIiwgImFsZyI6ICJIUzI1NiJ9.eyJ1c2VyX2lkIjogInB5dGhvbnR3MjAxNiJ9.qhevGfl16LBHjRG2wb6xDitbGt3lDK-2iUYCsLseCJY='

Test this token in https://jwt.io/

Page 28: 2016 pycontw web api authentication

We don’t need to reinvent the wheel

28

Page 29: 2016 pycontw web api authentication

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

PyJWT

Page 30: 2016 pycontw web api authentication

30

PyJWT

Django DRF JWT Authjson

hmac

base64

hashlibFlask-JWT

Page 31: 2016 pycontw web api authentication

PyJWT

>>> import jwt

>>> jwt_token = jwt.encode({ 'payload': ‘pycontw 2106’}, 'secret', algorithm='HS256')'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXlsb2FkIjoicHljb250dyAyMDE2In0.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

Page 32: 2016 pycontw web api authentication

Example Scenarios

32

Page 33: 2016 pycontw web api authentication

Copyright © 2016 ThroughTek Co., Ltd. All rights reserved. Confidential. Do not distribute. 33

• Generic applications

• Customization service

• Kalay Kit

• FW integration

micro-service system

Page 34: 2016 pycontw web api authentication

Kalay services

34

Users

Kalay AM Kalay DM

JWT

login

Kalay DC

mqtt/https

shared keys shared keys

shared keys

Kalay CloudKalay services

Kalay services

devices

actions (bind/view/control….)

with JWT

Page 35: 2016 pycontw web api authentication

Messaging API for Mobile Apps and Websites

● http://api.diuit.com/

Page 36: 2016 pycontw web api authentication

Authentication with JWT for security purpose1. User sends login request with credential2. Auth user on your server (account server)3. Request for Nonce on Diuit server4. Obtain nonce from Diuit server5. Use JWT to request session token6. Obtain session token from Diuit server7. Send session token back to messaging client8. 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

Page 37: 2016 pycontw web api authentication

Django REST framework JWTJSON Web Token Authentication support for Django REST Framework

37

Page 38: 2016 pycontw web api authentication

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)

Page 39: 2016 pycontw web api authentication

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/

Page 40: 2016 pycontw web api authentication

Flask-JWTAdd basic JWT features to your Flask application

40

https://pythonhosted.org/Flask-JWT/

Page 41: 2016 pycontw web api authentication

Flask-JWT

from flask import Flaskfrom flask_jwt import JWT, jwt_required, current_identityfrom 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:

Page 42: 2016 pycontw web api authentication

42

app = Flask(__name__)app.debug = Trueapp.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_identityif __name__ == '__main__': app.run()

Configuration

JWT_AUTH_URL_RULE:The authentication endpoint URL. Defaults to /auth

https://pythonhosted.org/Flask-JWT/

jwt working

Page 43: 2016 pycontw web api authentication

Recap● JWT (‘jot’) : header, payload, signature

● Stateless token-based authentication

● Use libraries

● PyJWT, Django DRF JWT , Flask-JWT

● Provide, refresh, verify JWT

43

Page 44: 2016 pycontw web api authentication

About JWTRef:

● 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

Page 45: 2016 pycontw web api authentication

Thank you!

Questions?

45