Authentication/Authentication history (Basic, Digest, Cookie, Session, Token, JWT, API key, HMAC).md
... ...
@@ -0,0 +1,363 @@
1
+https://medium.com/@iamprovidence/authentication-history-basic-digest-cookie-session-token-jwt-api-key-55d6c21be90b
2
+
3
+# Authentication history (Basic, Digest, Cookie, Session, Token, JWT, API key, HMAC) | by iamprovidence | Medium
4
+
5
+![iamprovidence](https://miro.medium.com/v2/resize:fill:88:88/1*5_4tdBAsyyi0qA4XgMD1xA.png)
6
+[iamprovidence](https://medium.com/@iamprovidence)
7
+
8
+Let’s say you are building an app. Nothing overcomplicated. Simple data storage like Google drive. Users can upload and view their files. The question is how do we make sure users can only view their files and not someone else?
9
+
10
+The naive approach would be to send `UserId` in every request to a server. It is not only naive but also creates a huge security hole! As soon as your users have basic knowledge of how the Internet works they will try sending requests to a server with a different `UserId`.
11
+
12
+The only valid option would be to let the server distinguish which user sent a request. There is a variety of authentication options, like Basic authentication, Digest, Cookie, Session, Token and JWT. If you are interested in getting deeper knowledge in what are those, which problems they solve, and their benefits and drawbacks, read this article to the very end.
13
+
14
+In case you are new here, there are other articles on this topic.
15
+
16
+Authentication theory:
17
+
18
+* **Authentication history (Basic, Digest, Cookie, Session, Token, JWT, API key, HMAC)**
19
+* [Token gang (Bearer token, Reference token, Opaque token, Self-contained token, JWT, Access token, ID token, Refresh token)](https://medium.com/@iamprovidence/token-gang-bearer-token-reference-token-opaque-token-self-contained-token-jwt-access-token-6e0191093cd0)
20
+* [OAuth 2.0 and OpenID in simple terms](https://medium.com/@iamprovidence/oauth-2-0-and-openid-in-simple-terms-7196089a1b29)
21
+
22
+How to implement authentication in C# environment:
23
+
24
+* [Cookie-based Authentication in ASP](https://medium.com/@iamprovidence/basic-authentication-in-asp-39c585f9e074)
25
+* [Authorization in ASP](https://medium.com/@iamprovidence/authorization-in-asp-1ffece002c3)
26
+* [Identity Server integration with ASP MVC](https://medium.com/@iamprovidence/identity-server-integration-with-asp-mvc-1e128e4f319f)
27
+* Identity Server for microservices
28
+* Identity Server integration with SPA
29
+* SSO with Identity server
30
+
31
+You may also check out some others stories:
32
+
33
+* What is authentication schema in ASP about?
34
+* Authorization policy under the hood
35
+* Encapsulate authentication with DelegatingHandler
36
+* How to parse token on client side
37
+
38
+Meanwhile, we are starting.
39
+
40
+Basic Authentication
41
+--------------------
42
+
43
+The simplest authentication mechanism is HTTP Basic Authentication. Here’s an overview of how it works:
44
+
45
+1. A user enters his login and password in the login form
46
+2. If the server successfully validates those, the client now can store the user’s login and password
47
+3. **User Authentication.** The client includes an `Authorization` header in all subsequent requests with the word "Basic" followed by a space and a base64-encoded string of the form "login:password".
48
+
49
+```
50
+HTTP: https://my-app.com/get-photos
51
+Authorization: Basic base64encode(login:password)
52
+```
53
+
54
+
55
+4\. **Server Verification.** The server, upon receiving the request, decodes the base64 string, retrieves the login and password, and verifies them against DB. If the credentials are valid, the server allows access to the requested resource; otherwise, it returns a `401 Unauthorized` status code.
56
+
57
+![](https://miro.medium.com/v2/resize:fit:720/format:webp/1*KrysFfhlfNhinn6pNJgXtQ.png)
58
+
59
+Despite its simplicity, Basic Authorization has multiple drawbacks:
60
+
61
+* **security.** credentials are sent in an easily decodable Base64-encoded format therefore should only be used in conjunction with HTTPS
62
+* **privacy.** user’s credentials are exposed and can not be used by other systems
63
+* **revocation.** the server has no way to end the user’s session
64
+* **storage.** user’s credential is stored in a browser and could be exposed
65
+* **performance.** additional db calls have to be made to validate credentials (consider adding cache)
66
+
67
+**Digest** Authentication
68
+-------------------------
69
+
70
+To overcome the shortcoming of the Basic Authentication a more secure way to transmit credentials was found.
71
+
72
+It involves hashing the username, password, and other information in the request, making it harder to intercept and decode:
73
+
74
+1. A user enters his login and password in the login form
75
+2. If the server successfully validates those, the client creates a hash based on login and password
76
+3. **User Authentication.** The client includes an `Authorization` header in all subsequent requests with the word "Digest" followed user’s login and generated hash:
77
+
78
+```
79
+HTTP: https://my-app.com/get-photos
80
+Authorization: Digest username="john", hash="5ccc069c403eb171e9517f40e41"
81
+```
82
+
83
+
84
+4\. **Server Verification.** The server, upon receiving the client’s request, performs its own hash calculations using the stored password. If the calculated hash matches the one sent by the client, access is granted.
85
+
86
+![](https://miro.medium.com/v2/resize:fit:720/format:webp/1*HrYsF7ryUfk11dSWrnh8uw.png)
87
+
88
+In practice it is a bit more complicated than that, but it is enough for you to understand Digest Authentication.
89
+
90
+This time we don’t send user’s password but a hash value, which is irreversible comparing to encoding. This approach is a bit more secure, but we still have issues:
91
+
92
+* **performance.** validation of credential cost time and resources
93
+* **revocation.** the server still has no way to end the user’s session
94
+
95
+Cookie
96
+------
97
+
98
+The traditional authentication approach on the web involves cookies.
99
+
100
+A cookie could be anything, a number, string, _serialized object_, and so on. However, for security reasons, the cookie responsible for authentication is encrypted.
101
+
102
+The usual flow of using cookies is as follows:
103
+
104
+1. A user enters his login and password in the login form
105
+2. If the server successfully validates those, it _issues_ an encrypted cookie. That cookie can also contain any additional information about the user like age, permissions, preferences etc
106
+3. **User Authentication.** The _user’s browser_ stores that cookie and includes it in all subsequent requests as a Cookie header:
107
+
108
+```
109
+HTTP: https://my-app.com/get-photos
110
+Cookie: uLfpKTEAAxgVbjjJs6S5RcXnQlLnK4knnz2zBa5wN3wO/zqQM4ZhAv604
111
+```
112
+
113
+
114
+4\. **Server Verification.** The server, upon receiving the client’s request, validates a cryptographic signature attached to the cookie, its expiration time, domain path etc. If the cookie sent by the client is valid, access is granted.
115
+
116
+![](https://miro.medium.com/v2/resize:fit:720/format:webp/1*jvZ9nHiR8E8M6wglFY-M3A.png)
117
+
118
+There are a few things worth noting:
119
+
120
+* **self-contained**. cookies are self-contained. It means the server can just verify its signature without the need to do a DB request. This is how validation cost issues were solved
121
+* **stateless**: the server does not need to store additional data. This simplifies server-side implementations and allows for easier horizontal scaling
122
+* **revocation**. server has multiple ways to terminate a user’s session (cookie expiration time, timeout session for inactive users, send invalidate cookie header)
123
+* **in-build support.** but the most lovely thing about cookies is that they are so common you don’t have to implement any code on the client side. Your browser will attach cookies on every request automatically. That is just ideal for [MPA](https://medium.com/@iamprovidence/frontend-side-architecture-evolution-mpa-spa-bd87fa32da8)
124
+
125
+Regardless of how good it sounds, there are always some caveats:
126
+
127
+* **performance.** cookies are sent out for every single request (even for requests that don’t require authentication)
128
+* **interoperability.** cookies work out of the box only in the browser. For all the other clients (desktop, mobile etc) you still would have to write code
129
+* **scale poorly.** cookies are bound to a server’s domain and, therefore are not applicable in [SPA](https://medium.com/@iamprovidence/frontend-side-architecture-evolution-mpa-spa-bd87fa32da8) or [microservices](https://medium.com/@iamprovidence/microservices-376bb3f553b7)
130
+* **security risks**: cookies are vulnerable to [CSRF attacks](https://medium.com/p/0d5de7c74569#8042). Extra protection measures should be implemented
131
+
132
+You can find an example of cookie-based authentication [here](https://medium.com/@iamprovidence/basic-authentication-in-asp-39c585f9e074).
133
+
134
+Session
135
+-------
136
+
137
+You can make cookies work in a [distributed environment](https://medium.com/@iamprovidence/microservices-376bb3f553b7) with sessions:
138
+
139
+1. A user enters his login and password in the login form
140
+2. If the server successfully validates those, it gets or _creates_ a user’s session in the database and _issues_ a cookie with the session id
141
+3. **User Authentication.** The _user’s browser_ stores that cookie and includes it in all subsequent requests as a `Cookie` header:
142
+
143
+```
144
+HTTP: https://my-app.com/get-photos
145
+Cookie: SessionId=270299
146
+```
147
+
148
+
149
+4\. **Server Verification.** The server, upon receiving the client’s request, validates the cookie and retrieves the session from the DB
150
+
151
+![](https://miro.medium.com/v2/resize:fit:720/format:webp/1*CrtvEXKp73yzLjRdMGJZOQ.png)
152
+
153
+A session is just a record in the database about a user. It contains all the data you would usually have in the cookie, but this time it is completely on the server side.
154
+
155
+Despite weak advantages:
156
+
157
+* **server-side storage.** sensitive data is not exposed to the client
158
+* **centralized control on the server side**. it is easier to implement features like session timeouts, account locking, and other security measures
159
+* **cross-domain communication.** a session can be utilized across a [distributed environment](https://medium.com/@iamprovidence/microservices-376bb3f553b7)
160
+
161
+You have almost the same issues as before:
162
+
163
+* **latency.** session validation requires DB call
164
+* **performance.** cookies are sent out for every single request
165
+* **interoperability.** cookies do not work on their own outside the browser
166
+* **scale poorly.** a database can be distributed too, which leads even to more issues
167
+* **security risks**: cookies are vulnerable to [CSRF attacks](https://medium.com/p/0d5de7c74569#8042). Extra protection measures should be implemented
168
+
169
+Token
170
+-----
171
+
172
+Long story short, token authentication is the same as the session one. We just no longer have cookies, and instead of session id, a random string is used, so it is harder to compromise it:
173
+
174
+1. A user enters his login and password in the login form
175
+2. If the server successfully validates those, it gets or creates a user’s session in the database and issues a random string related to this session called a token
176
+3. **User Authentication.** The client stores that token and includes it in all subsequent requests:
177
+
178
+```
179
+HTTP: https://my-app.com/get-photos
180
+Authorization: pS4zFXYx0URtDEkMWOcGunMgxA7cGyXYx0URtDEkMWOcGunMgxA7
181
+```
182
+
183
+
184
+4\. **Server Verification.** The server, upon receiving the client’s request, validates there is a session in the DB with such token. If so the access is granted
185
+
186
+![](https://miro.medium.com/v2/resize:fit:720/format:webp/1*ebT_G4S38w3Q2leWOhT9Mg.png)
187
+
188
+I know 😔. Cookies seemed to be such a good idea. So why would we get rid of it and use a token instead?
189
+
190
+* **interoperability.** token can be used on any device (browser, mobile, desktop)
191
+* **cross-domain communication.** support [distributed architecture](https://medium.com/@iamprovidence/microservices-376bb3f553b7)
192
+* **privacy.** no credential is exposed, so the token can be used by third-party
193
+* **server-side storage.** sensitive data is not exposed to the client
194
+* **centralized control on the server side**. it is easier to implement features like session timeouts, account locking, and other security measures
195
+
196
+However, we just get back to square one:
197
+
198
+* **no in-build support.** we have to implement everything by ourselves
199
+* **storage.** token stored on the client side can be [exposed](https://medium.com/p/0d5de7c74569#095b)
200
+* **performance.** token validation costs a DB request. For [microservices](https://medium.com/@iamprovidence/microservices-376bb3f553b7), it is even worse. You need an http call to an identity server that will do a DB request
201
+
202
+JWT
203
+---
204
+
205
+Finally, we grow up to good old JWT tokens. 😌
206
+
207
+So what is the deal with it? JWT tries to keep the benefits of token authentication but decreases performance issues. Do you remember how exactly the validation cost was reduced with cookies? 🤔 Cookies are self-contained. So let’s make our token self-contained.
208
+
209
+JWT (JSON Web Token) is a cryptographically secure token that contains all needed data inside itself in JSON format:
210
+
211
+```
212
+{
213
+ "alg": "HS256",
214
+ "typ": "JWT"
215
+}
216
+.
217
+{
218
+ "sub": "1234567890",
219
+ "name": "John Doe",
220
+ "iat": 1516239022
221
+}
222
+.
223
+signature
224
+```
225
+
226
+
227
+Additionally, it is encoded to make it more size concise. So the token above will be encoded to:
228
+
229
+```
230
+eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
231
+```
232
+
233
+
234
+The flow is pretty much the same as what we are used to:
235
+
236
+1. A user enters his login and password in the login form
237
+2. If the server successfully validates those, it issues a JWT token
238
+3. **User Authentication.** The client stores that token and includes an `Authorization` header in all subsequent requests with the word “Bearer” followed by a space and a JWT token:
239
+
240
+```
241
+HTTP: https://my-app.com/get-photos
242
+Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
243
+```
244
+
245
+
246
+4\. **Server Verification.** The server, upon receiving the client’s request, validates the [signature](https://medium.com/@iamprovidence/cryptography-for-kids-040516012acc#8da0) and grants access
247
+
248
+![](https://miro.medium.com/v2/resize:fit:720/format:webp/1*Vwvyqq_EGRC776ArI1HaiA.png)
249
+
250
+The benefits are:
251
+
252
+* **performance.** no database lookup since the token is self-contained
253
+* **interoperability.** the token can be used on any device (browser, mobile, desktop etc)
254
+* **stateless**: the server does not need to store additional data. This simplifies server-side implementations and allows for easier horizontal scaling
255
+* **cross-domain communication.** support [distributed architecture](https://medium.com/@iamprovidence/microservices-376bb3f553b7)
256
+* **privacy.** no credential is exposed, so the token can be used by third-party
257
+
258
+But remember about those issues:
259
+
260
+* **storage.** token still can be [hijacked](https://medium.com/p/0d5de7c74569#095b) by an attacker (can be partially fixed with a [refresh token](https://medium.com/@iamprovidence/token-gang-bearer-token-reference-token-opaque-token-self-contained-token-jwt-access-token-6e0191093cd0#0164))
261
+* **revocation.** the server has no way to end the user’s session (JWT token is valid even after a user logs out)
262
+* **no in-build support.** we need to write code (one can argue it is a benefit since it is more agile and flexible but I will let you decide)
263
+* **sensitive data exposure.** care must be taken not to include sensitive information in the token payload
264
+
265
+As you can see, even though JWT is so popular, it is not a panacea either.
266
+
267
+API Key
268
+-------
269
+
270
+Since we are already on this topic, a few final words for M2M authentication.
271
+
272
+The API Key flow is avoided for user authentication but is commonly used for machine-to-machine (M2M) communication or third-party integrations, where one software application or system interacts with another API (Application Programming Interfaces).
273
+
274
+Here is a basic overview of the API Key flow:
275
+
276
+1. Developers or administrators generate API keys beforehand
277
+2. **Server Authentication.** The client includes an `Authorization` header in all subsequent requests with the word "ApiKey" followed by the key:
278
+
279
+```
280
+HTTP: https://my-app.com/get-photos
281
+Authorization: ApiKey 9c403eb171e9517f40e415ccc069c403eb171e9517f40e41
282
+```
283
+
284
+
285
+You can also find an implementation where the API key is included as a query parameter:
286
+
287
+```
288
+HTTP: https://my-app.com/get-photos?
289
+ api-key=9c403eb171e9517f40e415ccc069c403eb171e9517f40e41
290
+```
291
+
292
+
293
+3\. **Server Verification.** The server, upon receiving the client’s request, validates the API key to check if it is legitimate and associated with a valid application
294
+
295
+![](https://miro.medium.com/v2/resize:fit:720/format:webp/1*od8EcajmH6w6dCim2oVRJg.png)
296
+
297
+Even though it is almost a standard it still has some minute flaws:
298
+
299
+* **storage.** can be stored insecurely, such as hardcoding them in source code, storing them in configuration files, or sharing them inappropriately
300
+* **no expiration.** they don’t expire unless explicitly revoked allowing hijackers to have infinite access to the API
301
+
302
+HMAC
303
+----
304
+
305
+It is also possible, that client exposes an endpoint to receive webhooks. This time, not the server, but **_the client_** needs to authenticate requests.
306
+
307
+Traditionally, webhooks are secured with [HMAC](https://medium.com/@iamprovidence/cryptography-for-kids-040516012acc#8da0) (Hash-based Message Authentication Code).
308
+
309
+Here’s an overview of how it works:
310
+
311
+1. The client sends an _authenticated_ request to subscribe to the server’s events
312
+2. The server validates the request, generates a random [_signing key_](https://medium.com/@iamprovidence/cryptography-for-kids-040516012acc#3521), and stores it. This key is issued in the response a single time
313
+
314
+```
315
+{
316
+ "signingKey": "sa13d"
317
+}
318
+```
319
+
320
+
321
+3\. **Server Authentication.** When an event occurs on the server, it generates a [signature](https://medium.com/@iamprovidence/cryptography-for-kids-040516012acc#8da0) by hashing the webhook’s payload along with a signing key
322
+
323
+Both payload and signature are included in the webhook:
324
+
325
+```
326
+{
327
+ "signature": "171e9517f40e415ccc06",
328
+ "payload": <object>
329
+}
330
+```
331
+
332
+
333
+4\. **Client Verification.** The client, upon receiving the webhook, calculates the signature in the same way (`signature = hash(content + signing key)`) and compares it to the one in the webhook. If they are the same, the request is considered to be legit and can be processed
334
+
335
+![](https://miro.medium.com/v2/resize:fit:720/format:webp/1*HTRNfctoNEBgEvujybJDhg.png)
336
+
337
+HMAC has some benefits over API keys:
338
+
339
+* **data integrity.** it not only authenticates the server but also ensures the request is untampered
340
+* **privacy.** API Key (Signing Key) is not sent directly and is not exposed if intercepted, even for developers' team
341
+* **uniqueness.** signature is unique for each webhook
342
+
343
+While it is common to use HMAC with webhooks, you can get use of it for traditional M2M communication. Just remember, that it adds:
344
+
345
+* **complexity.** HMAC is harder to implement compared to API key
346
+* **storage.** can be stored insecurely. If the key is compromised, all communications relying on it are vulnerable
347
+* **no expiration.** they don’t expire unless explicitly revoked
348
+* **sensitive data exposure.** the HMAC does not protect the payload’s confidentiality. If the payload contains sensitive data, it must be encrypted separately to ensure privacy
349
+* **performance.** both the client and the server require time to compute the HMAC, slowing down request processing
350
+
351
+Final Thoughts
352
+--------------
353
+
354
+And that is all for today 😌. In this article I was aiming to guide you through the authentication landscape, offering insights into the diverse tools and techniques that have shaped the authentication over time.
355
+
356
+It is essential not only to understand and be able to use any of those approaches in parallel but also to combine them. Regardless of how clean and experience-proved those ideas look, in practice, you would have to deal with a complete horror of legacy code 😁.
357
+
358
+It happens so, that authentication is so widely known and a completely misunderstood topic at the same time, that most of the time it results in a complete mess. I have seen JWT is stored in cookies, cookies used for API-only communication, or JWT for M2M. I have been through that kind of sh\*t you don’t even want to hear. Most of the time those implementations were done by me 😅. Don’t do as I have done. Be smarter. Learn ahead and find a solution that suits you best 🙃.
359
+
360
+Let me know in the comment what was your worst experience with authentication?💬
361
+Give this article a clap or a few if you like it 👏
362
+You can support me with a link below ☕️
363
+And don’t forget to follow if you are interested to read about all those authentication methods in detail ✅
... ...
\ No newline at end of file