A | B | C | D | E | F | G | H | ||
---|---|---|---|---|---|---|---|---|---|
1 | HTTP Basic Auth | Stateless Session Cookie | JWT | Stateful Session Cookie | Random Token | Full Request Signature | OAuth | ||
2 | Description | Pass username and password with every request | Signed or encrypted cookie with user information. Usually handled by web framework. | Signed or encrypted user info in an encoded json string. Handled by well tested libraries in every language | Standard session cookie, supported by most web frameworks and browsers. | A strong, secure random token that does not have any data in it, and cannot be guessed. This is equivalent to session id. | Popularized by AWS authentication. Shared secret between server and client. Client signs the complete request using the shared secret, server verifies it. See http://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html | Only use this when you have three parties - you, your users, and third party app developers that need your user data. If you don't have third party developers, OAuth is overkill | |
3 | When to use | For internal APIs that are used from server side only, and are low-value. | If you are building a web application only, and your framework supports it, and you do not have a distributed cache like redis/memcached. Don't implement this on your own. | Mobile, Web, Server side apps. Only if you are okay to forego revocation and inactivity based timeout. | If you are building a web application only, and can store sessions in database or a distributed cache | For web and mobile apps when you already have a distributed cache like redis/memcached. For server side apps, prefer JWT with per-request token. | Only for server side applications when you provide your clients a library to manage the cryptography, and only if you are concerned about replay attacks. In practice, using JWT for every request, and including the url and key request parameters in the JWT achieves most of the benefits of this approach without implementing the complex canonicalization algorithm | Only if you have external third party developers who want user specific data, and you need permission from your users before sharing their data with the third party. For anything else, OAuth is overkill. | |
4 | Where is data stored? | Server side. The username is passed in the request, the server validates it using the provided password, and then looks up whatever information it wants from it's database. | In the cookie | In the token | Stored server side either in memory or in database or in distributed cache or in file system. | Stored server side either in memory or in database or in distributed cache or in file system. | Server side. The "userid" is passed in the request, the signature tells the server it is indeed that user. The server can then look up whatever information it wants from it's database. | TBD | |
5 | Expiry | Not relevant. Upto the server to manage | Stored in the cookie | Stored in the token | Stored server side | Stored server side | Passed in the request, and usually valid for a very short time only. | ||
6 | Use Crypto? | No Cryptography | Yes, but usually handled by web framework | Yes, but usually handled by mature library | No Cryptography | No Cryptography | Yes. Outside of AWS libraries, there isn't a good standard implementation, so it will be painful to use if you don't provide client libraries | ||
7 | Inactivity based timeout | Not relevant. Don't use this technique for web based clients | Server has to overwrite the cookie with every request, setting a new expiry time. If the framework doesn't handle this alread, this can be painful | Painful. You have to use refresh tokens, which is added work for the client. You can maintain a last_seen_at flag in a database/cache, and use that to expire, but then you lose the benefits of being stateless | Yes. Easily handled out of the box in every web framework | Yes. With every request, increment the timeout on the server side. | Doesn't make sense. This approach only makes sense for server side applications, and in such applications inactivity based timeout does not make sense | ||
8 | Revocation | Not relevant. Don't use this technique for web based clients | Painful. You have to maintain a separte revocation list in a distributed store. Again, you lose the benefits of being stateless | Painful. You have to maintain a separate revocation list in a distributed store. Again, you lose the benefits of being stateless. | Possible, but exact capabilities depends on web framework | Yes. Simply delete the session data on the server side, and next request will be considered unauthenticated. | Yes, The server can easily deny the request. | ||
9 | Browser: Storage | Not relevant. Don't use this technique for web based clients | Implicit. Browser handles this automatically, no effort on part of the programmer | Explicit. Programmer has to store the token somewhere. Usually sessionStorage or localStorage. | Implicit. Browser handles this automatically, no effort on part of the programmer | Explicit. Programmer has to store the token somewhere. Usually sessionStorage or localStorage. | Not applicable. This technique is not suitable for web applications. | ||
10 | Passing Credentials | Passed in Authorization header Example: Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l Username and password are NOT encrypted | As cookie. Browser automatically sends this to the server | As request header - Authorization: Bearer <token> Programmer explicitly passes this with every request | As cookie. Browser automatically sends this to the server | As request header - Authorization: Bearer <token> Programmer explicitly passes this with every request | Passed in the Authorization header, but instead of "bearer", it will be some other custom scheme. AWS uses AWS4-HMAC-SHA256. Example: Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/iam/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=5d672d79c15b13162d9279b0855cfba6789a8edb4c82c400e06b5924a6f2b5d7 Programmer explicitly passes this with every request | ||
11 | Browser: CSRF Vulnerabilities | Vulnerable. Do not use basic authentication for web apps, unless it is a low value internal web application | Vulnerable. Programmers need to be careful to prevent CSRF | Not vulnerable, because token is passed explicity as a request header | Vulnerable. Programmers need to be careful to prevent CSRF | Not vulnerable, because token is passed explicity as a request header | Not applicable. This technique is not suitable for web applications. | ||
12 | Native mobile apps | Don't use basic authentication. Mobile apps cannot store the credentials safely, and users will not want to enter credentials for every request | Native mobile apps will find session based auth painful. Avoid session based auth if mobile apps are expected to use API | Mobile app users expect to login just once, and don't ever login again. JWT with a long expiry can work, but a better strategy is to use a secure random token with no information in it. | Native mobile apps will find session based auth painful. Avoid session based auth if mobile apps are expected to use API | Create the random token during first installation/login, and use that token throughout the life of the app. | Not applicable. This technique is not suitable for web applications - because the mobile app cannot keep secrets. | ||
13 | Server side apps | If you use HTTPS, then basic authentication is a good choice for server side only applications. It is the easiest to get started, and is well supported by clients and server frameworks | Server side apps will find session based auth painful. Avoid if server side apps are expected to use API | Create a private-public key pair, and let the client create the JWT with the private key and the server validate it using the public key. Alternatively, maintain a shared secret and use that to create the JWT. Prefer private/public key pair instead of shared secret. Create JWT on every request, and keep expiry very low. | Server side apps will find session based auth painful. Avoid if server side apps are expected to use API | This becomes similar to an API key that is passed by the client. Replay attacks are possible if someone gets the API key. For server to server apps, prefer JWT with public/private key pair | This is a preferred approach for server side applications where higher security is needed. In principle, it is similar to JWT with shared keys, except that in this approach everything is signed - the url, the parameters, the request headers and the request body. | ||
14 | Replay Attacks | Definitely possible. | Possible | Possible only if the expiry is high. If every request generates a new JWT (like in case of server side apps), then replay attacks becomes very difficult. | Possible | Possible | Because everything is signed, this makes replay attacks impossible | ||
15 | |||||||||
16 | |||||||||
17 | |||||||||
18 | |||||||||
19 | |||||||||
20 | |||||||||
21 | |||||||||
22 | |||||||||
23 | |||||||||
24 | |||||||||
25 | |||||||||
26 | |||||||||
27 | |||||||||
28 | |||||||||
29 | |||||||||
30 | |||||||||
31 | |||||||||
32 | |||||||||
33 | |||||||||
34 | |||||||||
35 | |||||||||
36 | |||||||||
37 | |||||||||
38 | |||||||||
39 | |||||||||
40 | |||||||||
41 | |||||||||
42 | |||||||||
43 | |||||||||
44 | |||||||||
45 | |||||||||
46 | |||||||||
47 | |||||||||
48 | |||||||||
49 | |||||||||
50 | |||||||||
51 | |||||||||
52 | |||||||||
53 | |||||||||
54 | |||||||||
55 | |||||||||
56 | |||||||||
57 | |||||||||
58 | |||||||||
59 | |||||||||
60 | |||||||||
61 | |||||||||
62 | |||||||||
63 | |||||||||
64 | |||||||||
65 | |||||||||
66 | |||||||||
67 | |||||||||
68 | |||||||||
69 | |||||||||
70 | |||||||||
71 | |||||||||
72 | |||||||||
73 | |||||||||
74 | |||||||||
75 | |||||||||
76 | |||||||||
77 | |||||||||
78 | |||||||||
79 | |||||||||
80 | |||||||||
81 | |||||||||
82 | |||||||||
83 | |||||||||
84 | |||||||||
85 | |||||||||
86 | |||||||||
87 | |||||||||
88 | |||||||||
89 | |||||||||
90 | |||||||||
91 | |||||||||
92 | |||||||||
93 | |||||||||
94 | |||||||||
95 | |||||||||
96 | |||||||||
97 | |||||||||
98 | |||||||||
99 | |||||||||
100 |