SlideShare a Scribd company logo
1 of 88
Download to read offline
JSON Web Tokens
Will Improve Your Life
John SJ Anderson • @genehack | Ohio LinuxFest • 30 Sep 2017
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 1
Hi, I’m John.
a/k/a @genehack
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 2
VP, Technology
Infinity
Interactive
iinteractive.com
@iinteractive
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 3
This is
my dog,
Sammy.a/k/a @sammyGenehack
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 4
So, what’s
a JWT?JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 5
jwt.io
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 6
What Does
That Even
Mean?
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 7
Holy RFCs, Batman
— RFC 7519 - JSON Web Token (JWT)
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 8
Holy RFCs, Batman
— RFC 7515 - JSON Web Signature (JWS)
— RFC 7516 - JSON Web Encryption (JWE)
— RFC 7517 - JSON Web Key (JWK)
— RFC 7518 - JSON Web Algorithms (JWA)
— RFC 7519 - JSON Web Token (JWT)
— RFC 7520 - Examples of Protecting Content Using JSON
Object Signing and Encryption (JOSE)
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 9
Sammy found
these RFCs
a bit …dry
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 10
Think of JWTs as…
— A lightweight alternative to cookies (kinda, sorta)
— …that also works with CLI, mobile, or even desktop apps
— An authorization or access control mechanism
— …kinda like OAuth but without losing your will to live
— Cross-domain friendly
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 11
Made of stuff you already know
— Plain ol’ JSON Objects (POJOs)
— Stringified, encoded, and cryptographically signed
— Transmitted over HTTP(S)
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 12
What do they look like?
— dot-delimited string ('.')
— 3 parts
— header
— payload
— signature
— Example: xxx.yyyyy.zzz
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 13
JWT teardown: header
— Plain ole JSON object
— Base64 encoded
— Typically metadata, such as token type and signing
algorithm
{
"alg": "HS256",
"typ": "JWT"
}
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 14
JWT teardown: payload
— Another Base64-encoded POJO
— Contains “claims” – just key-value data
— Types of keys: reserved, public, private
{
"name": "Ohio LinuxFest",
"admin": false,
"iat": 1488562999
}
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 15
JWT teardown: signature
— Encoded header POJO, plus
— Encoded payload POJO, plus
— A secret, plus
— Signing algorithm from header alg key
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 16
A word about my
code samples
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 17
Making a JWT
function base64EncodeJson (pojo) {
var jsonString = JSON.stringify(pojo);
var encoded = new Buffer(jsonString).toString("base64");
return encoded;
}
function hmacIt (string, secret) {
var hmac = crypto.createHmac("sha256" , secret);
hmac.update(string);
var signature = hmac.digest("hex");
return signature;
}
var header = {
"alg": "HS256",
"typ": "JWT"
};
var payload = {
"name": "Ohio LinuxFest",
"admin": false,
"iat": 1488562999
};
var secret = "be wery, wery qwiet, we're hunting JWTs";
var encodedHeader = base64EncodeJson(header);
var encodedPayload = base64EncodeJson(payload);
var signature = hmacIt(encodedHeader + "." + encodedPayload, secret);
var jwt = encodedHeader + "." + encodedPayload + "." + signature;
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 18
Helper function one
function base64EncodeJson (pojo) {
var jsonString = JSON.stringify(pojo);
var encoded = new Buffer(jsonString)
.toString("base64");
return encoded;
}
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 19
Helper function two
function hmacIt (string, secret) {
var hmac = crypto.createHmac("sha256" , secret);
hmac.update(string);
var signature = hmac.digest("hex");
return signature;
}
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 20
The actual data
var header = {
"alg": "HS256",
"typ": "JWT"
};
var payload = {
"name": "Ohio LinuxFest",
"admin": false,
"iat": 1488562999
};
var secret = "be wery, wery qwiet, we're hunting JWTs";
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 21
Actually generating the signature
var encodedHeader = base64EncodeJson(header);
var encodedPayload = base64EncodeJson(payload);
var signature = hmacIt(
encodedHeader + "." + encodedPayload,
secret
);
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 22
Assembling the token
var jwt = encodedHeader
+ "."
+ encodedPayload
+ "."
+ signature;
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 23
Hand-rolled, artisanal JWT
> console.log(jwt.split('.').join('.n'));
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJuYW1lIjoiT2hpbyBMaW51eEZlc3QiLCJhZG1pbiI6ZmFsc2UsImlhdCI6MTQ4ODU2Mjk5OX0=.
f2bdd1f7f0cfc975c0ae6e5c356812af748d6d589d64c9c97f02018166e6ae5e
The critical bit of all of this:
The signature means you can detect any attempts to modify
the header or the payload.
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 24
Validation
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 25
Validation
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 26
Validation
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 27
Validation
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 28
Libraries for DAYS
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 29
Libraries for DAYS
— .NET, Python, Node, Java, Javascript, Ruby, Perl, Go, PHP
— Haskell, Rust, Lua, Scala, Clojure, ObjectiveC, Swift, Delphi
— Support for your favorite language/platform is probably
not an issue
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 30
OK,
you’ve
got my
attentionJWTs WIYL! - Ohio LinuxFest 2017 – @genehack 31
How
do I
actually
use
JWTs?
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 32
Basic authn/authz usage
(image stolen from jwt.io)
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 33
Things to be aware of
— Payload/header NOT encrypted
— …so don’t send anything sensitive!
— Need to control expiration, re-issue, etc.
— Some APIs send a fresh JWT to the client per-request
— Sites other than issuing site can receive JWT
— …but they must share the secret to validate
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 34
How is it actually transmitted?
— Up to you! Various methods:
— As part of the URL in a GET
— In a POST body
— In the Authorization header using Bearer scheme:
Authorization: Bearer <token>
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 35
How would
you actually
use this
in an app?
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 36
Generate a token on login
app.post('/user/login', app.wrap(user_login));
var jwt = require('jwt'); // helper wrapper around 'jsonwebtoken'
function * user_login (req, res) {
if (! (req.body.email && req.body.password)) {
res.status(400);
res.json({message: 'invalid request'});
return;
}
var user = yield _fetch_user_by_email(req.body.email);
var claims;
if (_pw_validate(user.password, req.body.password)) {
claims = { user_id: user.id };
} else {
res.status(401);
res.header('WWW-Authenticate', 'Bearer realm=myapp');
res.json({ message: 'authorization required' });
return;
}
// sign the claim set and return the token in a header
var token = jwt.sign(claims);
res.append('X-MyApp-Token', token);
res.status(200);
}
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 37
Generate a token on login
app.post('/user/login', app.wrap(user_login));
var jwt = require('jwt'); // helper wrapper around 'jsonwebtoken'
function * user_login (req, res) {
if (! (req.body.email && req.body.password)) {
res.status(400);
res.json({message: 'invalid request'});
return;
}
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 38
Generate a token on login
var user = yield _fetch_user_by_email(req.body.email);
var claims;
if (_pw_validate(user.password, req.body.password)) {
claims = { user_id: user.id };
}
else {
res.status(401);
res.header('WWW-Authenticate', 'Bearer realm=myapp');
res.json({ message: 'authorization required' });
return;
}
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 39
Generate a token on login
// sign the claim set and return the token in a header
var token = jwt.sign(claims);
res.append('X-MyApp-Token', token);
res.status(200);
}
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 40
OK, that’s
how you
make one.
How do you
validate it?
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 41
Validate with a middleware
// enable JWT-verification middleware
var jwt = require('jwt'); // helper wrapper around 'jsonwebtoken'
app.use(function (req, res, next) {
// initialize the jwt object
req.jwt = {};
// now parse the Authorization header if it exists
Promise.resolve(req.headers.authorization).then(function (auth) {
// If the Authorization header is present and employs the correct
// Bearer scheme, extract the token and attempt to verify it.
if (auth) {
var scheme = auth.split(' ')[0];
var token = auth.split(' ')[1];
if (scheme == 'Bearer') {
return jwt.verify(token).catch(function (error) {
throw new Error('failed to verify claim');
});
}
}
throw new Error('authorization not attempted');
})
.then(function (payload) {
req.jwt = payload;
next();
})
.catch(function (error) {
// Allow login without JWT
if (req.path == '/user/login' && req.method == 'POST') {
return next();
}
res.status(401);
res.header('WWW-Authenticate', 'Bearer realm=myapp');
res.json({ message: 'authorization required' });
});
});
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 42
Validate with a middleware
// enable JWT-verification middleware
var jwt = require('jwt'); // helper wrapper around 'jsonwebtoken'
app.use(function (req, res, next) {
// initialize the jwt object
req.jwt = {};
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 43
Validate with a middleware
// now parse the Authorization header if it exists
Promise.resolve(req.headers.authorization).then(function (auth) {
// If the Authorization header is present and employs the correct
// Bearer scheme, extract the token and attempt to verify it.
if (auth) {
var scheme = auth.split(' ')[0];
var token = auth.split(' ')[1];
if (scheme === 'Bearer') {
return jwt.verify(token).catch(function (error) {
throw new Error('failed to verify claim');
});
}
}
throw new Error('authorization not attempted');
})
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 44
Validate with a middleware
.then(function (payload) {
req.jwt = payload;
next();
})
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 45
Validate with a middleware
.catch(function (error) {
// Allow login without JWT
if (req.path == '/user/login' && req.method == 'POST') {
return next();
}
res.status(401);
res.header('WWW-Authenticate', 'Bearer realm=myapp');
res.json({ message: 'authorization required' });
});
});
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 46
That’s cool.
What else
you got?
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 47
Pre-signed
Content
Requests
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 48
Document store application
— Client-side Angular
— Uses JWT for authentication and sessions
— Uses Authorization: Bearer scheme
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 49
PROBLEM!
How do you
display or download
images via browser?
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 50
SOLUTION
JWTs, of course
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 51
(What talk
did you think
this was?)JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 52
Solution
Generate a claim containing document ID:
{
"iat": 1497105117
"exp": 1497105177
"doc": 345345
}
NOTE: short expiration time
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 53
Solution
Sign it and put it in a URL:
/content/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0OTcxMDUxMTcsImV4cCI
6MTQ5NzEwNTE3NywiZG9jIjozNDUzNDV9.fKKCZgc2ckeONF9ELOcc9EgS-UPrCBX2bwoPmxjStdQ
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 54
Solution
Then on the server side, when you get a request like:
GET /content/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0OTcxMDUxMTcsImV4cC
I6MTQ5NzEwNTE3Ny wiZG9jIjozNDUzNDV9.fKKCZgc2ckeONF9ELOcc9EgS-UPrCBX2bwoPmxjStdQ
— Extract the token and validate
— Get the document ID from the payload
— Send back that document!
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 55
FAR
OUT
MAAAAANJWTs WIYL! - Ohio LinuxFest 2017 – @genehack 56
Recurring dilemma:
‘lightweight’
access control
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 57
Recurring dilemma: ‘lightweight’ access control
— Option 1: leave it wide open
— a/k/a the MongoDB or WTF,YOLO! pattern
— Option 2: implement full authn/authz subsystem
— …again
— Option 3: OAuth
— !!!!!!
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 58
Where’s the
middle
ground?
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 59
Where’s the
middle
ground?
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 60
A screen
door
for APIs
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 61
Authorization without authentication
— Scenario:
— You have an API
— You don’t want to make anybody authenticate to use it
— You don’t want it wide open to the Internet either
— a/k/a authz without authn
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 62
Solution: JWT with RSA keys
— Another option for secret: RSA key-pair
— Include the public key in the JWT header using JWK
— JSON Web Key, natch
— Allows clients of your API to make tokens
— …which you can verify
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 63
To set it up:
— Give authorized API client an RSA key-pair
— Record the fingerprint of the public key (important later!)
— You can even let the client generate the key-pair
— You just need the public key fingerprint
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 64
On the client side:
— They make a JWT, using the private key to sign
— They include the public key in the header
— Include iat (issued-at) and exp (expires) claims
— Send JWT in with API request
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 65
On the API side:
— Get the public key out of the header
— Validate the signature using the public key
— Validate that public key fingerprint is white-listed
— Signature produced with private key
— Public key is white-listed
— Therefore we know JWT is valid!
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 66
Things to be aware of:
— You still want to validate iat and exp and any other rules
— Your library should probably do that stuff for you,
mostly
— Again, nothing is encrypted, so don’t plan on sensitive
stuff in the payload or header
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 67
where’s
the
code?JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 68
Client side
use Crypt::JWT qw(encode_jwt);
use Crypt::PK::RSA;
use HTTP::Request;
# generate a JWT and POST a request
my $pri_key = Crypt::PK::RSA->new('./key.pri');
my $pub_key = Crypt::PK::RSA->new('./key.pub');
my $token = encode_jwt(
alg => 'RS512',
extra_headers => {
jwk => $pub_key->export_key_jwk('public', 1),
nonce => undef ,
},
key => $pri_key ,
payload => { iat => time() },
relative_exp => 1800,
);
HTTP::Request->new(
'POST' => 'https://example.com/endpoint',
['Authorization' => "Bearer $token"],
encode_json({ request => 'body' })
);
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 69
Client side: load the libraries & keys
use Crypt::JWT qw(encode_jwt);
use Crypt::PK::RSA;
use HTTP::Request;
my $pri_key = Crypt::PK::RSA->new('./key.pri');
my $pub_key = Crypt::PK::RSA->new('./key.pub');
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 70
Client side: make the token
my $token = encode_jwt(
alg => 'RS512',
extra_headers => {
jwk => $pub_key->export_key_jwk('public', 1),
nonce => undef ,
},
key => $pri_key ,
payload => { iat => time() },
relative_exp => 1800,
);
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 71
Client side: send the request
HTTP::Request->new(
'POST' => 'https://example.com/endpoint',
['Authorization' => "Bearer $token"],
encode_json({ request => 'body' })
);
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 72
Critical bit:adding the public key to the header
extra_headers => {
jwk => $pub_key->export_key_jwk('public', 1),
},
Pro tip: find an RSA library that supports exporting keys to
JWK format!
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 73
API side
use Crypt::JWT qw(decode_jwt);
use Crypt::PK::RSA;
use Dancer;
use Try::Tiny;
my $auth_header = request_header 'Authorization' ;
my $token;
status_401 unless ( $token ) = $auth_header =~ /^Bearer (.*)$/;
# try to decode it and confirm valid sig,
# and valid iat and exp claims
my( $header, $payload );
try {
( $header, $payload ) = decode_jwt(
token => $token , decode_header => 1 ,
accepted_alg => 'RS512' ,
verify_iat => 1 , verify_exp => 1
);
};
# no catch block, just drop the error, we're out of here in that case
status_401 unless $header and $payload;
# check that expiration time is less than one hour
status_401 unless $payload->{exp} - $payload->{iat} < 3600;
# check that the included public key is on the whitelist
my $pk = Crypt::PK::RSA->new;
$pk->import_key($header->{jwk});
my $thumbprint = $pk->export_key_jwk_thumbprint;
status_401 unless config->{whitelist}{$thumbprint};
# if we get here, we're all good!
...
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 74
API side: get the token
use Crypt::JWT qw(decode_jwt);
use Crypt::PK::RSA;
use Dancer;
use Try::Tiny;
my $auth_header = request_header 'Authorization' ;
my $token;
status_401 unless ( $token ) = $auth_header =~ /^Bearer (.*)$/;
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 75
API side: decode the token
# try to decode it and confirm valid sig,
# and valid iat and exp claims
my( $header, $payload );
try {
( $header, $payload ) = decode_jwt(
token => $token , decode_header => 1 ,
accepted_alg => 'RS512' ,
verify_iat => 1 , verify_exp => 1
);
};
# no catch block, just drop the error, we're out of here in that case
status_401 unless $header and $payload;
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 76
API side: decode the token
— Key in header wrong? FAILS
— Not right algorithm? FAILS
— Doesn’t have iat and exp? FAILS
ALL that validation is happening inside the library, so I don’t
have to worry about it.
— Me? WINS
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 77
API side: more checks
— We specify in the API docs that tokens can only be valid for
one hour
— Have to check that ourselves
— Also need to make sure this isn’t some random RSA
keypair
— Need to make sure we know this public key
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 78
API side: more checks
# check that expiration time is less than one hour
status_401 unless $payload->{exp} - $payload->{iat} < 3600;
# check that the included public key is on the whitelist
my $pk = Crypt::PK::RSA->new;
$pk->import_key($header->{jwk});
my $thumbprint = $pk->export_key_jwk_thumbprint;
status_401 unless config->{whitelist}{$thumbprint};
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 79
API side: THAT’S ALL FOLKS
# if we get here, we're all good!
— We know the public key in the header by its fingerprint,
— so we know the private key was used to sign the JWT
— (or it wouldn’t validate)
— and therefore the JWT is from the private key holder
— (who is, by definition, authorized!)
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 80
IMPORTANT NOTE!
This whole scheme does, of course, depend on the client
keeping the private key actually private
…but revocation is as simple as removing the fingerprint from
the whitelist.
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 81
More advanced usage
— Encrypted payloads (JWE)
— Nested JWT
See those RFCs!
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 82
JWT
backlash
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 83
Conclusions
— JWTs solve some really common problems.
— JWTs solve them in a pretty elegant way.
— This is really pretty damn cool.
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 84
Conclusions
— JWTs solve some really common problems.
— JWTs solve them in a pretty elegant way.
— This is really pretty damn cool!!!
— You should think about using JWTs.
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 85
Thanks!
— JWT.io / auth0.com folks
— Ohio LinuxFest organizers
— YOU!
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 86
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 87
Questions?
JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 88

More Related Content

What's hot

An Introduction to the Emerging JSON-Based Identity and Security Protocols (O...
An Introduction to the Emerging JSON-Based Identity and Security Protocols (O...An Introduction to the Emerging JSON-Based Identity and Security Protocols (O...
An Introduction to the Emerging JSON-Based Identity and Security Protocols (O...Brian Campbell
 
Java 11 - Keeping the Java Release Train on the Right Track
Java 11 - Keeping the Java Release Train on the Right TrackJava 11 - Keeping the Java Release Train on the Right Track
Java 11 - Keeping the Java Release Train on the Right TrackC4Media
 
CIS14: Developing with OAuth and OIDC Connect
CIS14: Developing with OAuth and OIDC ConnectCIS14: Developing with OAuth and OIDC Connect
CIS14: Developing with OAuth and OIDC ConnectCloudIDSummit
 
Session 5 - NGSI-LD Advanced Operations | Train the Trainers Program
Session 5 -  NGSI-LD Advanced Operations | Train the Trainers ProgramSession 5 -  NGSI-LD Advanced Operations | Train the Trainers Program
Session 5 - NGSI-LD Advanced Operations | Train the Trainers ProgramFIWARE
 
Symposium on Legal Regulation of Bitcoin, Blockchain & Cryptocurrencies
Symposium on Legal Regulation of Bitcoin, Blockchain & Cryptocurrencies Symposium on Legal Regulation of Bitcoin, Blockchain & Cryptocurrencies
Symposium on Legal Regulation of Bitcoin, Blockchain & Cryptocurrencies anupriti
 
Stateless Microservice Security via JWT and MicroProfile - ES
Stateless Microservice Security via JWT and MicroProfile - ES Stateless Microservice Security via JWT and MicroProfile - ES
Stateless Microservice Security via JWT and MicroProfile - ES Otavio Santana
 
Stateless Microservice Security via JWT and MicroProfile - Mexico
Stateless Microservice Security via JWT and MicroProfile - MexicoStateless Microservice Security via JWT and MicroProfile - Mexico
Stateless Microservice Security via JWT and MicroProfile - MexicoOtávio Santana
 
Stateless Microservice Security via JWT and MicroProfile - Guatemala
Stateless Microservice Security via JWT and MicroProfile - GuatemalaStateless Microservice Security via JWT and MicroProfile - Guatemala
Stateless Microservice Security via JWT and MicroProfile - GuatemalaOtávio Santana
 
JSON Web Tokens Will Improve Your Life
JSON Web Tokens Will Improve Your LifeJSON Web Tokens Will Improve Your Life
JSON Web Tokens Will Improve Your LifeJohn Anderson
 
Blockchain Fundamentals
Blockchain FundamentalsBlockchain Fundamentals
Blockchain FundamentalsBruno Lowagie
 
Distributed Search in Riak - Integrating Search in a NoSQL Database: Presente...
Distributed Search in Riak - Integrating Search in a NoSQL Database: Presente...Distributed Search in Riak - Integrating Search in a NoSQL Database: Presente...
Distributed Search in Riak - Integrating Search in a NoSQL Database: Presente...Lucidworks
 
Java Persistence Frameworks for MongoDB
Java Persistence Frameworks for MongoDBJava Persistence Frameworks for MongoDB
Java Persistence Frameworks for MongoDBMongoDB
 
Deciphering Explain Output
Deciphering Explain Output Deciphering Explain Output
Deciphering Explain Output MongoDB
 
Java Persistence Frameworks for MongoDB
Java Persistence Frameworks for MongoDBJava Persistence Frameworks for MongoDB
Java Persistence Frameworks for MongoDBTobias Trelle
 
Elasticsearch und die Java-Welt
Elasticsearch und die Java-WeltElasticsearch und die Java-Welt
Elasticsearch und die Java-WeltFlorian Hopf
 
Session 2 - NGSI-LD primer & Smart Data Models | Train the Trainers Program
Session 2 - NGSI-LD primer & Smart Data Models | Train the Trainers ProgramSession 2 - NGSI-LD primer & Smart Data Models | Train the Trainers Program
Session 2 - NGSI-LD primer & Smart Data Models | Train the Trainers ProgramFIWARE
 
Elastify you application: from SQL to NoSQL in less than one hour!
Elastify you application: from SQL to NoSQL in less than one hour!Elastify you application: from SQL to NoSQL in less than one hour!
Elastify you application: from SQL to NoSQL in less than one hour!David Pilato
 
Node.js 與 google cloud storage
Node.js 與 google cloud storageNode.js 與 google cloud storage
Node.js 與 google cloud storageonlinemad
 
Building Your First App with MongoDB
Building Your First App with MongoDBBuilding Your First App with MongoDB
Building Your First App with MongoDBMongoDB
 
Blockchain Technologies for Data Science
Blockchain Technologies for Data ScienceBlockchain Technologies for Data Science
Blockchain Technologies for Data ScienceBruno Gonçalves
 

What's hot (20)

An Introduction to the Emerging JSON-Based Identity and Security Protocols (O...
An Introduction to the Emerging JSON-Based Identity and Security Protocols (O...An Introduction to the Emerging JSON-Based Identity and Security Protocols (O...
An Introduction to the Emerging JSON-Based Identity and Security Protocols (O...
 
Java 11 - Keeping the Java Release Train on the Right Track
Java 11 - Keeping the Java Release Train on the Right TrackJava 11 - Keeping the Java Release Train on the Right Track
Java 11 - Keeping the Java Release Train on the Right Track
 
CIS14: Developing with OAuth and OIDC Connect
CIS14: Developing with OAuth and OIDC ConnectCIS14: Developing with OAuth and OIDC Connect
CIS14: Developing with OAuth and OIDC Connect
 
Session 5 - NGSI-LD Advanced Operations | Train the Trainers Program
Session 5 -  NGSI-LD Advanced Operations | Train the Trainers ProgramSession 5 -  NGSI-LD Advanced Operations | Train the Trainers Program
Session 5 - NGSI-LD Advanced Operations | Train the Trainers Program
 
Symposium on Legal Regulation of Bitcoin, Blockchain & Cryptocurrencies
Symposium on Legal Regulation of Bitcoin, Blockchain & Cryptocurrencies Symposium on Legal Regulation of Bitcoin, Blockchain & Cryptocurrencies
Symposium on Legal Regulation of Bitcoin, Blockchain & Cryptocurrencies
 
Stateless Microservice Security via JWT and MicroProfile - ES
Stateless Microservice Security via JWT and MicroProfile - ES Stateless Microservice Security via JWT and MicroProfile - ES
Stateless Microservice Security via JWT and MicroProfile - ES
 
Stateless Microservice Security via JWT and MicroProfile - Mexico
Stateless Microservice Security via JWT and MicroProfile - MexicoStateless Microservice Security via JWT and MicroProfile - Mexico
Stateless Microservice Security via JWT and MicroProfile - Mexico
 
Stateless Microservice Security via JWT and MicroProfile - Guatemala
Stateless Microservice Security via JWT and MicroProfile - GuatemalaStateless Microservice Security via JWT and MicroProfile - Guatemala
Stateless Microservice Security via JWT and MicroProfile - Guatemala
 
JSON Web Tokens Will Improve Your Life
JSON Web Tokens Will Improve Your LifeJSON Web Tokens Will Improve Your Life
JSON Web Tokens Will Improve Your Life
 
Blockchain Fundamentals
Blockchain FundamentalsBlockchain Fundamentals
Blockchain Fundamentals
 
Distributed Search in Riak - Integrating Search in a NoSQL Database: Presente...
Distributed Search in Riak - Integrating Search in a NoSQL Database: Presente...Distributed Search in Riak - Integrating Search in a NoSQL Database: Presente...
Distributed Search in Riak - Integrating Search in a NoSQL Database: Presente...
 
Java Persistence Frameworks for MongoDB
Java Persistence Frameworks for MongoDBJava Persistence Frameworks for MongoDB
Java Persistence Frameworks for MongoDB
 
Deciphering Explain Output
Deciphering Explain Output Deciphering Explain Output
Deciphering Explain Output
 
Java Persistence Frameworks for MongoDB
Java Persistence Frameworks for MongoDBJava Persistence Frameworks for MongoDB
Java Persistence Frameworks for MongoDB
 
Elasticsearch und die Java-Welt
Elasticsearch und die Java-WeltElasticsearch und die Java-Welt
Elasticsearch und die Java-Welt
 
Session 2 - NGSI-LD primer & Smart Data Models | Train the Trainers Program
Session 2 - NGSI-LD primer & Smart Data Models | Train the Trainers ProgramSession 2 - NGSI-LD primer & Smart Data Models | Train the Trainers Program
Session 2 - NGSI-LD primer & Smart Data Models | Train the Trainers Program
 
Elastify you application: from SQL to NoSQL in less than one hour!
Elastify you application: from SQL to NoSQL in less than one hour!Elastify you application: from SQL to NoSQL in less than one hour!
Elastify you application: from SQL to NoSQL in less than one hour!
 
Node.js 與 google cloud storage
Node.js 與 google cloud storageNode.js 與 google cloud storage
Node.js 與 google cloud storage
 
Building Your First App with MongoDB
Building Your First App with MongoDBBuilding Your First App with MongoDB
Building Your First App with MongoDB
 
Blockchain Technologies for Data Science
Blockchain Technologies for Data ScienceBlockchain Technologies for Data Science
Blockchain Technologies for Data Science
 

Similar to How to Use JSON Web Tokens (JWTs) for Authentication and Authorization

2016 pycontw web api authentication
2016 pycontw web api authentication 2016 pycontw web api authentication
2016 pycontw web api authentication Micron Technology
 
Modern API Security with JSON Web Tokens
Modern API Security with JSON Web TokensModern API Security with JSON Web Tokens
Modern API Security with JSON Web TokensJonathan LeBlanc
 
JWT: jku x5u
JWT: jku x5uJWT: jku x5u
JWT: jku x5usnyff
 
[OPD 2019] Attacking JWT tokens
[OPD 2019] Attacking JWT tokens[OPD 2019] Attacking JWT tokens
[OPD 2019] Attacking JWT tokensOWASP
 
RoadSec 2017 - Trilha AppSec - APIs Authorization
RoadSec 2017 - Trilha AppSec - APIs AuthorizationRoadSec 2017 - Trilha AppSec - APIs Authorization
RoadSec 2017 - Trilha AppSec - APIs AuthorizationErick Belluci Tedeschi
 
Nordic APIs - Automatic Testing of (RESTful) API Documentation
Nordic APIs - Automatic Testing of (RESTful) API DocumentationNordic APIs - Automatic Testing of (RESTful) API Documentation
Nordic APIs - Automatic Testing of (RESTful) API DocumentationRouven Weßling
 
API Days Paris - Automatic Testing of (RESTful) API Documentation
API Days Paris - Automatic Testing of (RESTful) API DocumentationAPI Days Paris - Automatic Testing of (RESTful) API Documentation
API Days Paris - Automatic Testing of (RESTful) API DocumentationRouven Weßling
 
Hypermedia APIs - GeekOut
Hypermedia APIs - GeekOutHypermedia APIs - GeekOut
Hypermedia APIs - GeekOutJan Kronquist
 
RAR and GNAP for VC HTTP API
RAR and GNAP for VC HTTP APIRAR and GNAP for VC HTTP API
RAR and GNAP for VC HTTP APIJustin Richer
 
2018 ecuador deconstruyendo y evolucionando la seguridad en servicios rest
2018 ecuador deconstruyendo y evolucionando la seguridad en servicios rest2018 ecuador deconstruyendo y evolucionando la seguridad en servicios rest
2018 ecuador deconstruyendo y evolucionando la seguridad en servicios restCésar Hernández
 
RoR Workshop - Web applications hacking - Ruby on Rails example
RoR Workshop - Web applications hacking - Ruby on Rails exampleRoR Workshop - Web applications hacking - Ruby on Rails example
RoR Workshop - Web applications hacking - Ruby on Rails exampleRailwaymen
 
I Don't Care About Security (And Neither Should You)
I Don't Care About Security (And Neither Should You)I Don't Care About Security (And Neither Should You)
I Don't Care About Security (And Neither Should You)Joel Lord
 
Nodejs and WebSockets
Nodejs and WebSocketsNodejs and WebSockets
Nodejs and WebSocketsGonzalo Ayuso
 
sf bay area dfir meetup (2016-04-30) - OsxCollector
sf bay area dfir meetup (2016-04-30) - OsxCollector   sf bay area dfir meetup (2016-04-30) - OsxCollector
sf bay area dfir meetup (2016-04-30) - OsxCollector Rishi Bhargava
 
前端MVC之BackboneJS
前端MVC之BackboneJS前端MVC之BackboneJS
前端MVC之BackboneJSZhang Xiaoxue
 
I Don't Care About Security (And Neither Should You)
I Don't Care About Security (And Neither Should You)I Don't Care About Security (And Neither Should You)
I Don't Care About Security (And Neither Should You)Joel Lord
 
API Days Australia - Automatic Testing of (RESTful) API Documentation
API Days Australia  - Automatic Testing of (RESTful) API DocumentationAPI Days Australia  - Automatic Testing of (RESTful) API Documentation
API Days Australia - Automatic Testing of (RESTful) API DocumentationRouven Weßling
 
Workshop KrakYourNet2016 - Web applications hacking Ruby on Rails example
Workshop KrakYourNet2016 - Web applications hacking Ruby on Rails example Workshop KrakYourNet2016 - Web applications hacking Ruby on Rails example
Workshop KrakYourNet2016 - Web applications hacking Ruby on Rails example Anna Klepacka
 

Similar to How to Use JSON Web Tokens (JWTs) for Authentication and Authorization (20)

2016 pycontw web api authentication
2016 pycontw web api authentication 2016 pycontw web api authentication
2016 pycontw web api authentication
 
Modern API Security with JSON Web Tokens
Modern API Security with JSON Web TokensModern API Security with JSON Web Tokens
Modern API Security with JSON Web Tokens
 
JWT: jku x5u
JWT: jku x5uJWT: jku x5u
JWT: jku x5u
 
[OPD 2019] Attacking JWT tokens
[OPD 2019] Attacking JWT tokens[OPD 2019] Attacking JWT tokens
[OPD 2019] Attacking JWT tokens
 
JWTs and JOSE in a flash
JWTs and JOSE in a flashJWTs and JOSE in a flash
JWTs and JOSE in a flash
 
RoadSec 2017 - Trilha AppSec - APIs Authorization
RoadSec 2017 - Trilha AppSec - APIs AuthorizationRoadSec 2017 - Trilha AppSec - APIs Authorization
RoadSec 2017 - Trilha AppSec - APIs Authorization
 
Socket.io
Socket.ioSocket.io
Socket.io
 
Nordic APIs - Automatic Testing of (RESTful) API Documentation
Nordic APIs - Automatic Testing of (RESTful) API DocumentationNordic APIs - Automatic Testing of (RESTful) API Documentation
Nordic APIs - Automatic Testing of (RESTful) API Documentation
 
API Days Paris - Automatic Testing of (RESTful) API Documentation
API Days Paris - Automatic Testing of (RESTful) API DocumentationAPI Days Paris - Automatic Testing of (RESTful) API Documentation
API Days Paris - Automatic Testing of (RESTful) API Documentation
 
Hypermedia APIs - GeekOut
Hypermedia APIs - GeekOutHypermedia APIs - GeekOut
Hypermedia APIs - GeekOut
 
RAR and GNAP for VC HTTP API
RAR and GNAP for VC HTTP APIRAR and GNAP for VC HTTP API
RAR and GNAP for VC HTTP API
 
2018 ecuador deconstruyendo y evolucionando la seguridad en servicios rest
2018 ecuador deconstruyendo y evolucionando la seguridad en servicios rest2018 ecuador deconstruyendo y evolucionando la seguridad en servicios rest
2018 ecuador deconstruyendo y evolucionando la seguridad en servicios rest
 
RoR Workshop - Web applications hacking - Ruby on Rails example
RoR Workshop - Web applications hacking - Ruby on Rails exampleRoR Workshop - Web applications hacking - Ruby on Rails example
RoR Workshop - Web applications hacking - Ruby on Rails example
 
I Don't Care About Security (And Neither Should You)
I Don't Care About Security (And Neither Should You)I Don't Care About Security (And Neither Should You)
I Don't Care About Security (And Neither Should You)
 
Nodejs and WebSockets
Nodejs and WebSocketsNodejs and WebSockets
Nodejs and WebSockets
 
sf bay area dfir meetup (2016-04-30) - OsxCollector
sf bay area dfir meetup (2016-04-30) - OsxCollector   sf bay area dfir meetup (2016-04-30) - OsxCollector
sf bay area dfir meetup (2016-04-30) - OsxCollector
 
前端MVC之BackboneJS
前端MVC之BackboneJS前端MVC之BackboneJS
前端MVC之BackboneJS
 
I Don't Care About Security (And Neither Should You)
I Don't Care About Security (And Neither Should You)I Don't Care About Security (And Neither Should You)
I Don't Care About Security (And Neither Should You)
 
API Days Australia - Automatic Testing of (RESTful) API Documentation
API Days Australia  - Automatic Testing of (RESTful) API DocumentationAPI Days Australia  - Automatic Testing of (RESTful) API Documentation
API Days Australia - Automatic Testing of (RESTful) API Documentation
 
Workshop KrakYourNet2016 - Web applications hacking Ruby on Rails example
Workshop KrakYourNet2016 - Web applications hacking Ruby on Rails example Workshop KrakYourNet2016 - Web applications hacking Ruby on Rails example
Workshop KrakYourNet2016 - Web applications hacking Ruby on Rails example
 

More from John Anderson

Introduction to Git (even for non-developers)
Introduction to Git (even for non-developers)Introduction to Git (even for non-developers)
Introduction to Git (even for non-developers)John Anderson
 
Logs are-magic-devfestweekend2018
Logs are-magic-devfestweekend2018Logs are-magic-devfestweekend2018
Logs are-magic-devfestweekend2018John Anderson
 
Logs Are Magic: Why Git Workflows and Commit Structure Should Matter To You
Logs Are Magic: Why Git Workflows and Commit Structure Should Matter To YouLogs Are Magic: Why Git Workflows and Commit Structure Should Matter To You
Logs Are Magic: Why Git Workflows and Commit Structure Should Matter To YouJohn Anderson
 
A static site generator should be your next language learning project
A static site generator should be your next language learning projectA static site generator should be your next language learning project
A static site generator should be your next language learning projectJohn Anderson
 
Do you want to be right or do you want to WIN?
Do you want to be right or do you want to WIN?Do you want to be right or do you want to WIN?
Do you want to be right or do you want to WIN?John Anderson
 
An Introduction to Git (even for non-developers)
An Introduction to Git (even for non-developers)An Introduction to Git (even for non-developers)
An Introduction to Git (even for non-developers)John Anderson
 
You got chocolate in my peanut butter! .NET on Mac & Linux
You got chocolate in my peanut butter! .NET on Mac & LinuxYou got chocolate in my peanut butter! .NET on Mac & Linux
You got chocolate in my peanut butter! .NET on Mac & LinuxJohn Anderson
 
A static site generator should be your next language learning project
A static site generator should be your next language learning projectA static site generator should be your next language learning project
A static site generator should be your next language learning projectJohn Anderson
 
Old Dogs & New Tricks: What's New with Perl5 This Century
Old Dogs & New Tricks: What's New with Perl5 This CenturyOld Dogs & New Tricks: What's New with Perl5 This Century
Old Dogs & New Tricks: What's New with Perl5 This CenturyJohn Anderson
 
Introduction to Git (even for non-developers!)
Introduction to Git (even for non-developers!)Introduction to Git (even for non-developers!)
Introduction to Git (even for non-developers!)John Anderson
 
Introduction to Git for Non-Developers
Introduction to Git for Non-DevelopersIntroduction to Git for Non-Developers
Introduction to Git for Non-DevelopersJohn Anderson
 
A Modest Introduction To Swift
A Modest Introduction To SwiftA Modest Introduction To Swift
A Modest Introduction To SwiftJohn Anderson
 
A static site generator should be your next language learning project
A static site generator should be your next language learning projectA static site generator should be your next language learning project
A static site generator should be your next language learning projectJohn Anderson
 
Logs Are Magic: Why Git Workflows and Commit Structure Should Matter To You
Logs Are Magic: Why Git Workflows and Commit Structure Should Matter To YouLogs Are Magic: Why Git Workflows and Commit Structure Should Matter To You
Logs Are Magic: Why Git Workflows and Commit Structure Should Matter To YouJohn Anderson
 
Old Dogs & New Tricks: What's New With Perl5 This Century
Old Dogs & New Tricks: What's New With Perl5 This CenturyOld Dogs & New Tricks: What's New With Perl5 This Century
Old Dogs & New Tricks: What's New With Perl5 This CenturyJohn Anderson
 
A Modest Introduction to Swift
A Modest Introduction to SwiftA Modest Introduction to Swift
A Modest Introduction to SwiftJohn Anderson
 
Logs Are Magic: Why Git Workflows and Commit Structure Should Matter To You
Logs Are Magic: Why Git Workflows and Commit Structure Should Matter To YouLogs Are Magic: Why Git Workflows and Commit Structure Should Matter To You
Logs Are Magic: Why Git Workflows and Commit Structure Should Matter To YouJohn Anderson
 
Friends Don't Let Friends Browse Unencrypted: Running a VPN for friends and f...
Friends Don't Let Friends Browse Unencrypted: Running a VPN for friends and f...Friends Don't Let Friends Browse Unencrypted: Running a VPN for friends and f...
Friends Don't Let Friends Browse Unencrypted: Running a VPN for friends and f...John Anderson
 
A Modest Introduction To Swift
A Modest Introduction To SwiftA Modest Introduction To Swift
A Modest Introduction To SwiftJohn Anderson
 

More from John Anderson (20)

#speakerlife
#speakerlife#speakerlife
#speakerlife
 
Introduction to Git (even for non-developers)
Introduction to Git (even for non-developers)Introduction to Git (even for non-developers)
Introduction to Git (even for non-developers)
 
Logs are-magic-devfestweekend2018
Logs are-magic-devfestweekend2018Logs are-magic-devfestweekend2018
Logs are-magic-devfestweekend2018
 
Logs Are Magic: Why Git Workflows and Commit Structure Should Matter To You
Logs Are Magic: Why Git Workflows and Commit Structure Should Matter To YouLogs Are Magic: Why Git Workflows and Commit Structure Should Matter To You
Logs Are Magic: Why Git Workflows and Commit Structure Should Matter To You
 
A static site generator should be your next language learning project
A static site generator should be your next language learning projectA static site generator should be your next language learning project
A static site generator should be your next language learning project
 
Do you want to be right or do you want to WIN?
Do you want to be right or do you want to WIN?Do you want to be right or do you want to WIN?
Do you want to be right or do you want to WIN?
 
An Introduction to Git (even for non-developers)
An Introduction to Git (even for non-developers)An Introduction to Git (even for non-developers)
An Introduction to Git (even for non-developers)
 
You got chocolate in my peanut butter! .NET on Mac & Linux
You got chocolate in my peanut butter! .NET on Mac & LinuxYou got chocolate in my peanut butter! .NET on Mac & Linux
You got chocolate in my peanut butter! .NET on Mac & Linux
 
A static site generator should be your next language learning project
A static site generator should be your next language learning projectA static site generator should be your next language learning project
A static site generator should be your next language learning project
 
Old Dogs & New Tricks: What's New with Perl5 This Century
Old Dogs & New Tricks: What's New with Perl5 This CenturyOld Dogs & New Tricks: What's New with Perl5 This Century
Old Dogs & New Tricks: What's New with Perl5 This Century
 
Introduction to Git (even for non-developers!)
Introduction to Git (even for non-developers!)Introduction to Git (even for non-developers!)
Introduction to Git (even for non-developers!)
 
Introduction to Git for Non-Developers
Introduction to Git for Non-DevelopersIntroduction to Git for Non-Developers
Introduction to Git for Non-Developers
 
A Modest Introduction To Swift
A Modest Introduction To SwiftA Modest Introduction To Swift
A Modest Introduction To Swift
 
A static site generator should be your next language learning project
A static site generator should be your next language learning projectA static site generator should be your next language learning project
A static site generator should be your next language learning project
 
Logs Are Magic: Why Git Workflows and Commit Structure Should Matter To You
Logs Are Magic: Why Git Workflows and Commit Structure Should Matter To YouLogs Are Magic: Why Git Workflows and Commit Structure Should Matter To You
Logs Are Magic: Why Git Workflows and Commit Structure Should Matter To You
 
Old Dogs & New Tricks: What's New With Perl5 This Century
Old Dogs & New Tricks: What's New With Perl5 This CenturyOld Dogs & New Tricks: What's New With Perl5 This Century
Old Dogs & New Tricks: What's New With Perl5 This Century
 
A Modest Introduction to Swift
A Modest Introduction to SwiftA Modest Introduction to Swift
A Modest Introduction to Swift
 
Logs Are Magic: Why Git Workflows and Commit Structure Should Matter To You
Logs Are Magic: Why Git Workflows and Commit Structure Should Matter To YouLogs Are Magic: Why Git Workflows and Commit Structure Should Matter To You
Logs Are Magic: Why Git Workflows and Commit Structure Should Matter To You
 
Friends Don't Let Friends Browse Unencrypted: Running a VPN for friends and f...
Friends Don't Let Friends Browse Unencrypted: Running a VPN for friends and f...Friends Don't Let Friends Browse Unencrypted: Running a VPN for friends and f...
Friends Don't Let Friends Browse Unencrypted: Running a VPN for friends and f...
 
A Modest Introduction To Swift
A Modest Introduction To SwiftA Modest Introduction To Swift
A Modest Introduction To Swift
 

Recently uploaded

2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdfAndrey Devyatkin
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZABSYZ Inc
 
Best Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITBest Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITmanoharjgpsolutions
 
What’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesWhat’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesVictoriaMetrics
 
Osi security architecture in network.pptx
Osi security architecture in network.pptxOsi security architecture in network.pptx
Osi security architecture in network.pptxVinzoCenzo
 
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingOpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingShane Coughlan
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogueitservices996
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorTier1 app
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Rob Geurden
 
Patterns for automating API delivery. API conference
Patterns for automating API delivery. API conferencePatterns for automating API delivery. API conference
Patterns for automating API delivery. API conferencessuser9e7c64
 
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...Bert Jan Schrijver
 
Understanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM ArchitectureUnderstanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM Architecturerahul_net
 
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxThe Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxRTS corp
 
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesAmazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesKrzysztofKkol1
 
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...OnePlan Solutions
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfDrew Moseley
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsSafe Software
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonLeveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonApplitools
 

Recently uploaded (20)

2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZ
 
Best Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITBest Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh IT
 
What’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesWhat’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 Updates
 
Osi security architecture in network.pptx
Osi security architecture in network.pptxOsi security architecture in network.pptx
Osi security architecture in network.pptx
 
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingOpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogue
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryError
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...
 
Patterns for automating API delivery. API conference
Patterns for automating API delivery. API conferencePatterns for automating API delivery. API conference
Patterns for automating API delivery. API conference
 
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
 
Understanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM ArchitectureUnderstanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM Architecture
 
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxThe Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
 
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesAmazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
 
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdf
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data Streams
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonLeveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
 

How to Use JSON Web Tokens (JWTs) for Authentication and Authorization

  • 1. JSON Web Tokens Will Improve Your Life John SJ Anderson • @genehack | Ohio LinuxFest • 30 Sep 2017 JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 1
  • 2. Hi, I’m John. a/k/a @genehack JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 2
  • 4. This is my dog, Sammy.a/k/a @sammyGenehack JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 4
  • 5. So, what’s a JWT?JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 5
  • 6. jwt.io JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 6
  • 7. What Does That Even Mean? JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 7
  • 8. Holy RFCs, Batman — RFC 7519 - JSON Web Token (JWT) JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 8
  • 9. Holy RFCs, Batman — RFC 7515 - JSON Web Signature (JWS) — RFC 7516 - JSON Web Encryption (JWE) — RFC 7517 - JSON Web Key (JWK) — RFC 7518 - JSON Web Algorithms (JWA) — RFC 7519 - JSON Web Token (JWT) — RFC 7520 - Examples of Protecting Content Using JSON Object Signing and Encryption (JOSE) JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 9
  • 10. Sammy found these RFCs a bit …dry JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 10
  • 11. Think of JWTs as… — A lightweight alternative to cookies (kinda, sorta) — …that also works with CLI, mobile, or even desktop apps — An authorization or access control mechanism — …kinda like OAuth but without losing your will to live — Cross-domain friendly JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 11
  • 12. Made of stuff you already know — Plain ol’ JSON Objects (POJOs) — Stringified, encoded, and cryptographically signed — Transmitted over HTTP(S) JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 12
  • 13. What do they look like? — dot-delimited string ('.') — 3 parts — header — payload — signature — Example: xxx.yyyyy.zzz JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 13
  • 14. JWT teardown: header — Plain ole JSON object — Base64 encoded — Typically metadata, such as token type and signing algorithm { "alg": "HS256", "typ": "JWT" } JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 14
  • 15. JWT teardown: payload — Another Base64-encoded POJO — Contains “claims” – just key-value data — Types of keys: reserved, public, private { "name": "Ohio LinuxFest", "admin": false, "iat": 1488562999 } JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 15
  • 16. JWT teardown: signature — Encoded header POJO, plus — Encoded payload POJO, plus — A secret, plus — Signing algorithm from header alg key JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 16
  • 17. A word about my code samples JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 17
  • 18. Making a JWT function base64EncodeJson (pojo) { var jsonString = JSON.stringify(pojo); var encoded = new Buffer(jsonString).toString("base64"); return encoded; } function hmacIt (string, secret) { var hmac = crypto.createHmac("sha256" , secret); hmac.update(string); var signature = hmac.digest("hex"); return signature; } var header = { "alg": "HS256", "typ": "JWT" }; var payload = { "name": "Ohio LinuxFest", "admin": false, "iat": 1488562999 }; var secret = "be wery, wery qwiet, we're hunting JWTs"; var encodedHeader = base64EncodeJson(header); var encodedPayload = base64EncodeJson(payload); var signature = hmacIt(encodedHeader + "." + encodedPayload, secret); var jwt = encodedHeader + "." + encodedPayload + "." + signature; JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 18
  • 19. Helper function one function base64EncodeJson (pojo) { var jsonString = JSON.stringify(pojo); var encoded = new Buffer(jsonString) .toString("base64"); return encoded; } JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 19
  • 20. Helper function two function hmacIt (string, secret) { var hmac = crypto.createHmac("sha256" , secret); hmac.update(string); var signature = hmac.digest("hex"); return signature; } JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 20
  • 21. The actual data var header = { "alg": "HS256", "typ": "JWT" }; var payload = { "name": "Ohio LinuxFest", "admin": false, "iat": 1488562999 }; var secret = "be wery, wery qwiet, we're hunting JWTs"; JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 21
  • 22. Actually generating the signature var encodedHeader = base64EncodeJson(header); var encodedPayload = base64EncodeJson(payload); var signature = hmacIt( encodedHeader + "." + encodedPayload, secret ); JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 22
  • 23. Assembling the token var jwt = encodedHeader + "." + encodedPayload + "." + signature; JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 23
  • 24. Hand-rolled, artisanal JWT > console.log(jwt.split('.').join('.n')); eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJuYW1lIjoiT2hpbyBMaW51eEZlc3QiLCJhZG1pbiI6ZmFsc2UsImlhdCI6MTQ4ODU2Mjk5OX0=. f2bdd1f7f0cfc975c0ae6e5c356812af748d6d589d64c9c97f02018166e6ae5e The critical bit of all of this: The signature means you can detect any attempts to modify the header or the payload. JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 24
  • 25. Validation JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 25
  • 26. Validation JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 26
  • 27. Validation JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 27
  • 28. Validation JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 28
  • 29. Libraries for DAYS JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 29
  • 30. Libraries for DAYS — .NET, Python, Node, Java, Javascript, Ruby, Perl, Go, PHP — Haskell, Rust, Lua, Scala, Clojure, ObjectiveC, Swift, Delphi — Support for your favorite language/platform is probably not an issue JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 30
  • 31. OK, you’ve got my attentionJWTs WIYL! - Ohio LinuxFest 2017 – @genehack 31
  • 32. How do I actually use JWTs? JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 32
  • 33. Basic authn/authz usage (image stolen from jwt.io) JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 33
  • 34. Things to be aware of — Payload/header NOT encrypted — …so don’t send anything sensitive! — Need to control expiration, re-issue, etc. — Some APIs send a fresh JWT to the client per-request — Sites other than issuing site can receive JWT — …but they must share the secret to validate JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 34
  • 35. How is it actually transmitted? — Up to you! Various methods: — As part of the URL in a GET — In a POST body — In the Authorization header using Bearer scheme: Authorization: Bearer <token> JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 35
  • 36. How would you actually use this in an app? JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 36
  • 37. Generate a token on login app.post('/user/login', app.wrap(user_login)); var jwt = require('jwt'); // helper wrapper around 'jsonwebtoken' function * user_login (req, res) { if (! (req.body.email && req.body.password)) { res.status(400); res.json({message: 'invalid request'}); return; } var user = yield _fetch_user_by_email(req.body.email); var claims; if (_pw_validate(user.password, req.body.password)) { claims = { user_id: user.id }; } else { res.status(401); res.header('WWW-Authenticate', 'Bearer realm=myapp'); res.json({ message: 'authorization required' }); return; } // sign the claim set and return the token in a header var token = jwt.sign(claims); res.append('X-MyApp-Token', token); res.status(200); } JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 37
  • 38. Generate a token on login app.post('/user/login', app.wrap(user_login)); var jwt = require('jwt'); // helper wrapper around 'jsonwebtoken' function * user_login (req, res) { if (! (req.body.email && req.body.password)) { res.status(400); res.json({message: 'invalid request'}); return; } JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 38
  • 39. Generate a token on login var user = yield _fetch_user_by_email(req.body.email); var claims; if (_pw_validate(user.password, req.body.password)) { claims = { user_id: user.id }; } else { res.status(401); res.header('WWW-Authenticate', 'Bearer realm=myapp'); res.json({ message: 'authorization required' }); return; } JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 39
  • 40. Generate a token on login // sign the claim set and return the token in a header var token = jwt.sign(claims); res.append('X-MyApp-Token', token); res.status(200); } JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 40
  • 41. OK, that’s how you make one. How do you validate it? JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 41
  • 42. Validate with a middleware // enable JWT-verification middleware var jwt = require('jwt'); // helper wrapper around 'jsonwebtoken' app.use(function (req, res, next) { // initialize the jwt object req.jwt = {}; // now parse the Authorization header if it exists Promise.resolve(req.headers.authorization).then(function (auth) { // If the Authorization header is present and employs the correct // Bearer scheme, extract the token and attempt to verify it. if (auth) { var scheme = auth.split(' ')[0]; var token = auth.split(' ')[1]; if (scheme == 'Bearer') { return jwt.verify(token).catch(function (error) { throw new Error('failed to verify claim'); }); } } throw new Error('authorization not attempted'); }) .then(function (payload) { req.jwt = payload; next(); }) .catch(function (error) { // Allow login without JWT if (req.path == '/user/login' && req.method == 'POST') { return next(); } res.status(401); res.header('WWW-Authenticate', 'Bearer realm=myapp'); res.json({ message: 'authorization required' }); }); }); JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 42
  • 43. Validate with a middleware // enable JWT-verification middleware var jwt = require('jwt'); // helper wrapper around 'jsonwebtoken' app.use(function (req, res, next) { // initialize the jwt object req.jwt = {}; JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 43
  • 44. Validate with a middleware // now parse the Authorization header if it exists Promise.resolve(req.headers.authorization).then(function (auth) { // If the Authorization header is present and employs the correct // Bearer scheme, extract the token and attempt to verify it. if (auth) { var scheme = auth.split(' ')[0]; var token = auth.split(' ')[1]; if (scheme === 'Bearer') { return jwt.verify(token).catch(function (error) { throw new Error('failed to verify claim'); }); } } throw new Error('authorization not attempted'); }) JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 44
  • 45. Validate with a middleware .then(function (payload) { req.jwt = payload; next(); }) JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 45
  • 46. Validate with a middleware .catch(function (error) { // Allow login without JWT if (req.path == '/user/login' && req.method == 'POST') { return next(); } res.status(401); res.header('WWW-Authenticate', 'Bearer realm=myapp'); res.json({ message: 'authorization required' }); }); }); JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 46
  • 47. That’s cool. What else you got? JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 47
  • 48. Pre-signed Content Requests JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 48
  • 49. Document store application — Client-side Angular — Uses JWT for authentication and sessions — Uses Authorization: Bearer scheme JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 49
  • 50. PROBLEM! How do you display or download images via browser? JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 50
  • 51. SOLUTION JWTs, of course JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 51
  • 52. (What talk did you think this was?)JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 52
  • 53. Solution Generate a claim containing document ID: { "iat": 1497105117 "exp": 1497105177 "doc": 345345 } NOTE: short expiration time JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 53
  • 54. Solution Sign it and put it in a URL: /content/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0OTcxMDUxMTcsImV4cCI 6MTQ5NzEwNTE3NywiZG9jIjozNDUzNDV9.fKKCZgc2ckeONF9ELOcc9EgS-UPrCBX2bwoPmxjStdQ JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 54
  • 55. Solution Then on the server side, when you get a request like: GET /content/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0OTcxMDUxMTcsImV4cC I6MTQ5NzEwNTE3Ny wiZG9jIjozNDUzNDV9.fKKCZgc2ckeONF9ELOcc9EgS-UPrCBX2bwoPmxjStdQ — Extract the token and validate — Get the document ID from the payload — Send back that document! JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 55
  • 56. FAR OUT MAAAAANJWTs WIYL! - Ohio LinuxFest 2017 – @genehack 56
  • 57. Recurring dilemma: ‘lightweight’ access control JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 57
  • 58. Recurring dilemma: ‘lightweight’ access control — Option 1: leave it wide open — a/k/a the MongoDB or WTF,YOLO! pattern — Option 2: implement full authn/authz subsystem — …again — Option 3: OAuth — !!!!!! JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 58
  • 59. Where’s the middle ground? JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 59
  • 60. Where’s the middle ground? JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 60
  • 61. A screen door for APIs JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 61
  • 62. Authorization without authentication — Scenario: — You have an API — You don’t want to make anybody authenticate to use it — You don’t want it wide open to the Internet either — a/k/a authz without authn JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 62
  • 63. Solution: JWT with RSA keys — Another option for secret: RSA key-pair — Include the public key in the JWT header using JWK — JSON Web Key, natch — Allows clients of your API to make tokens — …which you can verify JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 63
  • 64. To set it up: — Give authorized API client an RSA key-pair — Record the fingerprint of the public key (important later!) — You can even let the client generate the key-pair — You just need the public key fingerprint JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 64
  • 65. On the client side: — They make a JWT, using the private key to sign — They include the public key in the header — Include iat (issued-at) and exp (expires) claims — Send JWT in with API request JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 65
  • 66. On the API side: — Get the public key out of the header — Validate the signature using the public key — Validate that public key fingerprint is white-listed — Signature produced with private key — Public key is white-listed — Therefore we know JWT is valid! JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 66
  • 67. Things to be aware of: — You still want to validate iat and exp and any other rules — Your library should probably do that stuff for you, mostly — Again, nothing is encrypted, so don’t plan on sensitive stuff in the payload or header JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 67
  • 68. where’s the code?JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 68
  • 69. Client side use Crypt::JWT qw(encode_jwt); use Crypt::PK::RSA; use HTTP::Request; # generate a JWT and POST a request my $pri_key = Crypt::PK::RSA->new('./key.pri'); my $pub_key = Crypt::PK::RSA->new('./key.pub'); my $token = encode_jwt( alg => 'RS512', extra_headers => { jwk => $pub_key->export_key_jwk('public', 1), nonce => undef , }, key => $pri_key , payload => { iat => time() }, relative_exp => 1800, ); HTTP::Request->new( 'POST' => 'https://example.com/endpoint', ['Authorization' => "Bearer $token"], encode_json({ request => 'body' }) ); JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 69
  • 70. Client side: load the libraries & keys use Crypt::JWT qw(encode_jwt); use Crypt::PK::RSA; use HTTP::Request; my $pri_key = Crypt::PK::RSA->new('./key.pri'); my $pub_key = Crypt::PK::RSA->new('./key.pub'); JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 70
  • 71. Client side: make the token my $token = encode_jwt( alg => 'RS512', extra_headers => { jwk => $pub_key->export_key_jwk('public', 1), nonce => undef , }, key => $pri_key , payload => { iat => time() }, relative_exp => 1800, ); JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 71
  • 72. Client side: send the request HTTP::Request->new( 'POST' => 'https://example.com/endpoint', ['Authorization' => "Bearer $token"], encode_json({ request => 'body' }) ); JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 72
  • 73. Critical bit:adding the public key to the header extra_headers => { jwk => $pub_key->export_key_jwk('public', 1), }, Pro tip: find an RSA library that supports exporting keys to JWK format! JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 73
  • 74. API side use Crypt::JWT qw(decode_jwt); use Crypt::PK::RSA; use Dancer; use Try::Tiny; my $auth_header = request_header 'Authorization' ; my $token; status_401 unless ( $token ) = $auth_header =~ /^Bearer (.*)$/; # try to decode it and confirm valid sig, # and valid iat and exp claims my( $header, $payload ); try { ( $header, $payload ) = decode_jwt( token => $token , decode_header => 1 , accepted_alg => 'RS512' , verify_iat => 1 , verify_exp => 1 ); }; # no catch block, just drop the error, we're out of here in that case status_401 unless $header and $payload; # check that expiration time is less than one hour status_401 unless $payload->{exp} - $payload->{iat} < 3600; # check that the included public key is on the whitelist my $pk = Crypt::PK::RSA->new; $pk->import_key($header->{jwk}); my $thumbprint = $pk->export_key_jwk_thumbprint; status_401 unless config->{whitelist}{$thumbprint}; # if we get here, we're all good! ... JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 74
  • 75. API side: get the token use Crypt::JWT qw(decode_jwt); use Crypt::PK::RSA; use Dancer; use Try::Tiny; my $auth_header = request_header 'Authorization' ; my $token; status_401 unless ( $token ) = $auth_header =~ /^Bearer (.*)$/; JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 75
  • 76. API side: decode the token # try to decode it and confirm valid sig, # and valid iat and exp claims my( $header, $payload ); try { ( $header, $payload ) = decode_jwt( token => $token , decode_header => 1 , accepted_alg => 'RS512' , verify_iat => 1 , verify_exp => 1 ); }; # no catch block, just drop the error, we're out of here in that case status_401 unless $header and $payload; JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 76
  • 77. API side: decode the token — Key in header wrong? FAILS — Not right algorithm? FAILS — Doesn’t have iat and exp? FAILS ALL that validation is happening inside the library, so I don’t have to worry about it. — Me? WINS JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 77
  • 78. API side: more checks — We specify in the API docs that tokens can only be valid for one hour — Have to check that ourselves — Also need to make sure this isn’t some random RSA keypair — Need to make sure we know this public key JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 78
  • 79. API side: more checks # check that expiration time is less than one hour status_401 unless $payload->{exp} - $payload->{iat} < 3600; # check that the included public key is on the whitelist my $pk = Crypt::PK::RSA->new; $pk->import_key($header->{jwk}); my $thumbprint = $pk->export_key_jwk_thumbprint; status_401 unless config->{whitelist}{$thumbprint}; JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 79
  • 80. API side: THAT’S ALL FOLKS # if we get here, we're all good! — We know the public key in the header by its fingerprint, — so we know the private key was used to sign the JWT — (or it wouldn’t validate) — and therefore the JWT is from the private key holder — (who is, by definition, authorized!) JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 80
  • 81. IMPORTANT NOTE! This whole scheme does, of course, depend on the client keeping the private key actually private …but revocation is as simple as removing the fingerprint from the whitelist. JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 81
  • 82. More advanced usage — Encrypted payloads (JWE) — Nested JWT See those RFCs! JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 82
  • 83. JWT backlash JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 83
  • 84. Conclusions — JWTs solve some really common problems. — JWTs solve them in a pretty elegant way. — This is really pretty damn cool. JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 84
  • 85. Conclusions — JWTs solve some really common problems. — JWTs solve them in a pretty elegant way. — This is really pretty damn cool!!! — You should think about using JWTs. JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 85
  • 86. Thanks! — JWT.io / auth0.com folks — Ohio LinuxFest organizers — YOU! JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 86
  • 87. JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 87
  • 88. Questions? JWTs WIYL! - Ohio LinuxFest 2017 – @genehack 88