Work in progress!
Auth scheme
An authentication scheme is a method or recipe to pass credentials from a user to an authenticating system.
Authorization: <authentication type> <credential as base64>
Example:
Authorization: Basic <name:password>
Authorization: Bearer <oauth token>
HTTP Basic Authentication
More about this flow here: https://en.wikipedia.org/wiki/Basic_access_authentication#Protocol
OAuth
Access a resource with a token instead of using a login/password.
i.e. Flickr uses OAuth to allow third-party services to post and edit pictures on their behalf, without them having to give out their flickr username and password.
OpenId vs oAuth
OpenID is intended for federated authentication. A client accepts an identity assertion from any provider (although clients are free to whitelist or blacklist providers).
OAuth is currently better suited for authorization, because further interactions after authentication are built into the protocol, but both protocols are evolving. OpenID and its extensions could be used for authorization, and OAuth can be used for authentication, which can be thought of as a no-op authorization.
http://stackoverflow.com/a/1344271/1132522
Tokens
Bearer token
The gist is to use the Basic HTTP Authentication, but with a token instead of real credentials.
Typically JWT is sent in the Authorization header using the Bearer schema (hence “bearer token”). But it can also be stored in a cookie or other.
Authorization: Bearer <token>
Example:
Bearer tokens; that is, presenting a well-formed, non-expired, non-revoked auth token directly to an endpoint is accepted as sufficient proof of customer authentication.
A request authorization approach in which a token is presented directly to a service endpoint for purposes of establishing identity and/or obtaining access. Because these tokens will grant access to anyone in possession of the token, it is important to protect the confidentiality of these tokens, at rest and in transit (e.g. via access control and/or encryption, such as full-volume encryption, TLS, etc.).
There’s no server-side state associated with bearer tokens, so there’s no way to list all the authenticated sessions.
Access Token and Refresh token
Split token model
Refresh token/access token model, as described in the OAuth 2.0 specification http://tools.ietf.org/html/rfc6749#section-1.4, to achieve a balance of efficiency for services, and support for revocation.
Refresh token
A “token-granting-token,” often issued to a client directly following an authentication. The refresh token is used to obtain access tokens from a token service. Refresh tokens are not (and must not be) sent directly to service endpoints (see below). The refresh token is implemented as a bearer token.
Access Token
The access token is presented as part of an access/authorization request to a service endpoint, as a bearer token. Access tokens are typically, by design, short-lived, such that a client must obtain a new access token periodically to continue accessing a service endpoint. This provides an opportunity for revocation; for example, when a refresh token is revoked on the server side (e.g., via a password change or “manage my devices” workflow), it can no longer be used to obtain new access tokens. In this case, the client must obtain a new refresh token (usually via an explicit authentication, like entering a password) before obtaining a new access token for use with service endpoints.
JSON Web Token – JWT
Typically sent in the Authorization header using the Bearer schema (see Bearer token).
But can also be stored and set via cookies or other!
Why use a token anyways?
This is important because it is better to pass a token (that can expire, and have limited scope) to your API than a username and password!
If the password is compromised, keys to the castle.
The idea is that you present your hard credentials once, and then get a token to use in place of the hard credentials.
Why is it called JSON Web Token?
B/c it’s a token and it contains JSON. It could be an XML token or other form of token. JWT are famous these days.
Composition
JWT tokens are composed of 3 parts.: Header.Body.Signature
Body
The body contains the juicy bits. It is a JSON object giving your information about the user such as roles, etc.
You can save whatever you want inside this object. The default are:
“Sub”: Who this person is (sub, short for subject)
“Scope”: What this person can access with this token (scope)
“Exp”: When the token expires (exp)
“Iss”: Who issued the token (iss, short for issuer)
Claim
Every property (key value) inside of this object is a claim.
Header
The header contain information about the token itself.
They can be cryptographically signed and encrypted to prevent tampering on the client side.
Signature
Signature hash that can be used to verify the integrity of the token (if you have the secret key that was used to sign it).
JTI Claim = unique ID for a token The jti claim can be used to prevent the JWT from being replayed. The jti value is a case-sensitive string. Use of this claim is OPTIONAL. Json web signature: https://tools.ietf.org/html/rfc7515 Jason web ecnryption: https://tools.ietf.org/html/rfc7516
https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage
Tokens Are Signed, Not Encrypted
A JSON Web Token is comprised of three parts: the header, payload, and signature.
The format of a JWT is header.payload.signature.
If we were to sign a JWT with the HMACSHA256 algorithm, the secret ‘shhhh’ and the payload of:
{“sub”: “1234567890”,
“name” : “Ado Kukic” ,
“admin” : true}
The signature would be:
Y47kJvnHzU9qeJIN48_bVna6O0EDFiMiQ9LpNVDFymM
And the JWT generated would be:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFkbyBLdWtpYyIsImFkbWluIjp0cnVlLCJpYXQiOjE0NjQyOTc4ODV9.Y47kJvnHzU9qeJIN48_bVna6O0EDFiMiQ9LpNVDFymM
The very important thing to note here, is that, this token is signed by the HMAC SHA 256 algorithm, and the header and payload are Base64URL encoded, it is not encrypted.
If I go to jwt.io, paste this token and select the HMACSHA256 algorithm, I could decode the token and read its contents. Therefore, it should go without saying that sensitive data, such as passwords, should never be stored in the payload.
Is it possible to encrypt the token?
Of course, If you must store sensitive data in the payload or your use case calls for the JWT to be obscured, you can use JSON Web Encryption (JWE). JWE allows you to encrypt the contents of a JWT so that it is not readable by anyone but the server.
More
JWT’s allow you to store any type of metadata, as long as it’s valid JSON. Stateless, no mapping required server side.
Performance impact?
When using the cookie based authentication, the back-end has to do a lookup, whether that be a traditional SQL database or a NoSQL alternative, and the roundtrip is likely to take longer compared to decoding a token. Additionally, since you can store additional data inside the JWT, such as the users permission level, you can save yourself additional lookup calls to get and process the requested data.
Well you can cache too! To avoid database roundtrips.
JWT Size
The biggest disadvantage of token authentication is the size of JWTs. A session cookie is relatively tiny compared to even the smallest JWT.
Where to Store Tokens?
With token-based auth, you are given the choice of where to store the JWT.
Storing the token
2 main ways to store the token, cookies or web storage (local storage).
See Cookies vs LocalStorage.
Cookie vs Local Storage
Why cookies instead of LocalStorage for storing the JWT ?
The main reason to use cookies over (localstorage + auth header) are:
Security – LocalStorage can be read by any javascript code included in your app. Cookies which are httpOnly cannot be read by client code. This makes cookie option more secure (XSS).
Ease – Cookies are automatically transferred and a header need not be set. This solves the issue where a service may have it’s own admin page like wallace. If the auth header was required, you will never be able to access the service admin page since browser won’t be able to set the header itself.
Downside with cookies is that they make CSRF attacks.
But:
Cookies are limited to 4KB. You must have a light JWT token (I prefer that!).
So basically why not storing a simple session GUID at the end?
Request the token with your hard credentials:
HTTP/1.1
POST /token
Host: galaxies.com
Content-Type: application/x-www-form-urlencoded
username=tom@galaxies.com&password=androm
The response will defer deepening of the storage type.
Web Storage (local storage or session storage)
The respose could be:
HTTP/1.1 200 OK
{
“access_token”: “eyJhbGciOiJIUzI1NiIsI.eyJpc3MiOiJodHRwczotcGxlL.mFrs3Zo8eaSNcxiNfvRh9dqKP4F1cB”,
“expires_in”:3600
}
It’s up to you to call the stprage API to save the token and to retrieve it.
To pass the access token back to your protected APIs, you would use the HTTP Authorization Header and the Bearerscheme.
The request that your SPA would make would resemble:
HTTP/1.1
GET /stars/pollux
Host: galaxies.com
Authorization: Bearer eyJhbGciOiJIUzI1
If cookie
The response would use the Set-CookieHTTP header:
HTTP/1.1 200 OK
Set-Cookie: access_token=eyJhbGciOiJIUzI1NiIsI.eyJpc3MiOiJodHRwczotcGxlL.mFrs3Zo8eaSNcxiNfvRh9dqKP4F1cB; Secure; HttpOnly;
To pass the access token back to your protected APIs on the same domain, the browser would automatically include the cookie value. The request to your protected API would resemble:
GET /stars/pollux
Host: galaxies.com
Cookie: access_token=eyJhbGciOiJIU
So, What’s the difference?
Both are stateless because all the information your API needs is in the JWT.
No further check needed (Andrew: technically, it’s better to not overload the JWT but to map the user id to the roles saved in DB etc).
Security
Web storage
LocalStorage is accessible to JS in the same domain only. Via XSS attacks attackers can easily get local storage info.
Unlike cookies (via HttpOnly) – as a storage mechanism, Web Storage does not enforce any secure standards during transfer.
ALso, whoever reads Web Storage and uses it must do their due diligence to ensure they always send the JWT over HTTPS and never HTTP (as opposed to the Secure flag for Cookies).
Cookies
HttpOnly
If HttpOnly set to True, cannot be accessed through JS.
More flags to increase cookie security over here: Cookies and security.
XSS
XSS, in a nutshell, is a type of vulnerability where an attacker can inject JavaScript that will run on your page.
See XSS – CrosS Site Scripting.
CSRF
Cross-site request forgery (CSRF). A CSRF attack is a type of attack that occurs when a malicious web site, email, or blog causes a user’s web browser to perform an unwanted action on a trusted site on which the user is currently authenticated.
See Cross-Site Request Forgery – CSRF.
Leave a Reply
Want to join the discussion?Feel free to contribute!