Basic HTTP Authentication is defined in RFC 7617.
The Basic authentication scheme is based on the model that the client needs to authenticate itself with a user-id and a password for each protection space ("realm"). The realm value is a free-form string that can only be compared for equality with other realms on that server. The server will service the request only if it can validate the user-id and password for the protection space applying to the requested resource.
https://www.rfc-editor.org/rfc/rfc7617.html
Although Basic HTTP Authentication is rarely used nowadays, it is useful to understand as it brings together concepts of User, User Identity, Operation, Permission and Protection Space.
These will be involved in the securing of APIs using HTTP Bearer Authentication in a later chapter.
For the rest of this chapter we’ll explore Basic Authentication by setting up the following resources:
-
A document at
https://site.test/protected-by-basic-auth/document.html
which requires the User can perform the Operationhttps://site.test/operations/get-protected-resource
. We’ll called this the protected document. This is explained in Create the protected resource. -
A Permission to allow Alice to access this protected document. This is added in Permit Alice to access the protected resource.
-
A Protection Space that requires HTTP Basic Authentication. This is done in Establish the Protection Space.
-
A User Identity for Alice, including a username/password pair, that Alice can use to authenticate. This is added in Setting Alice’s password.
How HTTP 'Basic' Authentication works in Site shows the interaction between the components.
skinparam monochrome true autonumber actor Alice as user participant browser participant "/protected-by-basic-auth/document.html" as document participant Pass as pass database XTDB browser -> document: GET document <- XTDB: Lookup protection spaces\n(one is found for 'Basic' auth) document -> pass: Check permission to perform\nhttps://site.test/operations/get-protected-resource document <- pass: Denied browser <- document: 401 Unauthorized\nwith WWW-Authenticate header\nincluding realm value 'Wonderland' user <- browser: "Please login to Wonderland" user -> browser: Enters 'alice' and 'garden' browser -> document: GET with Authorization header\nwith base64 encoded username/password pair document <- XTDB: Lookup protection spaces\n(one is found for 'Basic' auth) document -> pass: Match credentials pass <- XTDB: User Identity found pass -> XTDB: Create new Subject document <- pass: 'Alice' set as the Subject document -> pass: Check permission to perform\nhttps://site.test/operations/get-protected-resource document <- pass: Allowed browser <- document: 200 OK
link:../../test/juxt/book.clj[role=include]
link:../../test/juxt/book.clj[role=include]
link:../../test/juxt/book.clj[role=include]
To login via Basic Authentication, Alice needs a password. We’ll set her a
password of garden
.
Adding a password for Alice demonstrates how we can call the Operation we created in [ex-create-operation-put-user-identity] to give Alice an extra identity.
Add a User Identity for Alice:
link:../../test/juxt/book.clj[role=include]
First test without providing credentials:
curl -i https://site.test/protected-by-basic-auth/document.html
This should return a 401 Unauthorized
response similar to this:
HTTP/1.1 401 Unauthorized Server: nginx/1.20.2 Date: Thu, 26 May 2022 09:34:20 GMT Content-Type: text/plain;charset=utf-8 Content-Length: 14 Connection: keep-alive WWW-Authenticate: Basic realm=Wonderland site-request-id: https://site.test/_site/requests/ea86d312c56eeba257f4b817 permissions-policy: interest-cohort=() Unauthorized
Now add the credentials:
curl -i https://site.test/protected-by-basic-auth/document.html -u alice:garden
This should return a 200 OK
response similar to this:
HTTP/1.1 200 OK Server: nginx/1.20.2 Date: Thu, 26 May 2022 09:34:41 GMT Content-Type: text/html;charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive site-request-id: https://site.test/_site/requests/df6b1ce54223971978873604 permissions-policy: interest-cohort=() <p>This is a protected message that those authorized are allowed to read.</p>
Tip
|
Try providing an invalid password. What do you get back? |
Tip
|
Try accessing https://site.test/protected-by-basic-auth/document.html in a browser. What happens?
|