KEMBAR78
2016 pycontw web api authentication | PDF
Authentication
with JSON Web Tokens
2016. 06. 04
pyconTW
Shuhsi Lin
Data Engineer of Throughtek
JSON Web Tokens
2
JWT
“jot”
3
1. Why we need authorization
2. The idea of Authorization Server
3. How to implement JWT
- PyJWT
- Django & Flask
4
Agenda
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
sucitw@gmail.com
shuhsi_lin@tutk.com
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)
Copyright © 2016 ThroughTek Co., Ltd. All rights reserved. Confidential. Do not distribute. 7
• Generic applications
• Customization service
• Kalay Kit
• FW integration
micro-service system
Turnkey Solution for Rapid IoT Deployment
Kalay Platform
What is Kalay?
9
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
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)
A server has to know
who is requesting the resource
12
How has authentication been done in web?
13
● Server based
● Token based
Server based authentication
14
user id/password
Problems from Server based authentication
● Sessions
● Scalability
● Cross-Origin Resource Sharing (CORS)
● Cross-Site Request Forgery (CSRF)
15
Token based authentication
16
user id/password
Stateless
Token based authentication
● Stateless and scalable servers
● Mobile application ready
● Pass authentication to other applications
● Extra security
17
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
JWT looks like?
19
Three strings separated by “.”
aaaaaaaaa.bbbbbbbbb.ccccccccccc
header payload signature
20
https://jwt.io/#debugger-io
don’t put sensitive data here
How usually JSON Web Tokens work ?
21
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 <json web token>
create JWT
Check JWT
send responses
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
How to implement it in
python ?
24
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']
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']
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.
eyJ1c2VyX2lkIjogInB5dGhvbnR3MjAxNiJ9.qhevGfl16LBHjRG2wb6xDitbGt3lDK-
2iUYCsLseCJY='
Test this token in https://jwt.io/
We don’t need to
reinvent the
wheel
28
29
https://jwt.io/#libraries-io
PyJWT
30
PyJWT
Django DRF JWT Auth
json
hmac
base64
hashlib
Flask-JWT
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
Example Scenarios
32
Copyright © 2016 ThroughTek Co., Ltd. All rights reserved. Confidential. Do not distribute. 33
• Generic applications
• Customization service
• Kalay Kit
• FW integration
micro-service system
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
Messaging API for Mobile Apps and Websites
● http://api.diuit.com/
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
Django REST framework JWT
JSON Web Token Authentication support for Django REST Framework
37
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)
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/
Flask-JWT
Add basic JWT features to your Flask application
40
https://pythonhosted.org/Flask-JWT/
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:
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
Recap
● JWT (‘jot’) : header, payload, signature
● Stateless token-based authentication
● Use libraries
● PyJWT, Django DRF JWT , Flask-JWT
● Provide, refresh, verify JWT
43
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
Thank you!
Questions?
45

2016 pycontw web api authentication

  • 1.
    Authentication with JSON WebTokens 2016. 06. 04 pyconTW Shuhsi Lin Data Engineer of Throughtek
  • 2.
  • 3.
  • 4.
    1. Why weneed authorization 2. The idea of Authorization Server 3. How to implement JWT - PyJWT - Django & Flask 4 Agenda
  • 5.
    About Me Data Engineerof Throughtek Currently working with - IoT -PaaS - Streaming processing framework - WebAPI - Lurking in PyHug, Taipei.py and various Meetups 5 Shuhsi Lin sucitw@gmail.com shuhsi_lin@tutk.com
  • 6.
    I A A Identity “Whoare you?” 6 Authentication “OK, how can you prove it?” Authorization “What can you do?” Identity and Access Management (IAM)
  • 7.
    Copyright © 2016ThroughTek Co., Ltd. All rights reserved. Confidential. Do not distribute. 7 • Generic applications • Customization service • Kalay Kit • FW integration micro-service system
  • 8.
    Turnkey Solution forRapid IoT Deployment Kalay Platform
  • 9.
  • 10.
    Copyright © 2016ThroughTek 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
  • 11.
    Copyright © 2016ThroughTek 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)
  • 12.
    A server hasto know who is requesting the resource 12
  • 13.
    How has authenticationbeen done in web? 13 ● Server based ● Token based
  • 14.
  • 15.
    Problems from Serverbased authentication ● Sessions ● Scalability ● Cross-Origin Resource Sharing (CORS) ● Cross-Site Request Forgery (CSRF) 15
  • 16.
  • 17.
    Token based authentication ●Stateless and scalable servers ● Mobile application ready ● Pass authentication to other applications ● Extra security 17
  • 18.
    18 https://jwt.io/ 2,506 6,120 https://github.com/search?q=jwt http://stackoverflow.com/search?q=jwt ● Compactand Self-contained ● Across different programming languages ● Passed around easily
  • 19.
    JWT looks like? 19 Threestrings separated by “.” aaaaaaaaa.bbbbbbbbb.ccccccccccc header payload signature
  • 20.
  • 21.
    How usually JSONWeb Tokens work ? 21
  • 22.
    How usually JSONWeb Tokens work ? 22 POST login/ user id/password https://auth0.com/learn/json-web-tokens/ return JWT token request with Header Authorization: Bearer <json web token> create JWT Check JWT send responses
  • 23.
    What do weput 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
  • 24.
    How to implementit in python ? 24
  • 25.
    25 In [1]: importjson 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']
  • 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']
  • 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. eyJ1c2VyX2lkIjogInB5dGhvbnR3MjAxNiJ9.qhevGfl16LBHjRG2wb6xDitbGt3lDK- 2iUYCsLseCJY=' Test this token in https://jwt.io/
  • 28.
    We don’t needto reinvent the wheel 28
  • 29.
  • 30.
    30 PyJWT Django DRF JWTAuth json hmac base64 hashlib Flask-JWT
  • 31.
    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
  • 32.
  • 33.
    Copyright © 2016ThroughTek Co., Ltd. All rights reserved. Confidential. Do not distribute. 33 • Generic applications • Customization service • Kalay Kit • FW integration micro-service system
  • 34.
    Kalay services Users Kalay AM KalayDM 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
  • 35.
    Messaging API forMobile Apps and Websites ● http://api.diuit.com/
  • 36.
    Authentication with JWTfor 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
  • 37.
    Django REST frameworkJWT JSON Web Token Authentication support for Django REST Framework 37
  • 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)
  • 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/
  • 40.
    Flask-JWT Add basic JWTfeatures to your Flask application 40 https://pythonhosted.org/Flask-JWT/
  • 41.
    Flask-JWT from flask importFlask 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:
  • 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
  • 43.
    Recap ● JWT (‘jot’): header, payload, signature ● Stateless token-based authentication ● Use libraries ● PyJWT, Django DRF JWT , Flask-JWT ● Provide, refresh, verify JWT 43
  • 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
  • 45.