我一直在讓自己跟上HTTP 基本身份驗證的速度。
我知道這從根本上來說是一種不安全的訪問機制(即使通過 HTTPS 使用,它總是應該如此)但我認識到HTTP 基本身份驗證并非完全沒有效用,我想熟悉它,即使情況很少出現我可能會在其中部署它。
到目前為止我的理解:
經過一番閱讀,我明白了:
- 服務器可以通過回傳來請求對資源的授權
401 (unauthorised) - 一個
WWW-Authenticate回應報頭確定認證被用來訪問該資源將是Basic HTTP Basic Authentication要求:- a) 用戶通過瀏覽器生成的控制臺提交用戶名和密碼;或者那個
- b) 一旦手動成功提交,相同的用戶名和密碼組合將通過附加到每個 HTTP 請求的
Authorization請求頭自動提交
到現在為止還挺好。
需要注意的問題:
我也知道HTTP 基本身份驗證存在一些問題,這些問題隨著時間的推移而發展,例如:
- 某些瀏覽器不再接受 URL 語法,例如
https://mylogin:[email protected]/my-resource.html - 如果 PHP 通過CGI或FastCGI運行,那么提交的授權憑證將不會被傳遞到
$_SERVER['HTTP_AUTHORIZATION']除非部署了黑客 - 最常見的建議是通過以下方式重寫 URL.htaccess mod_rewrite
以及從一開始就一直存在的其他問題,例如:
- “注銷” HTTP 基本身份驗證是一個重要問題,因為它從未打算或設計為具有注銷機制
拼圖的缺失部分:
但是,我仍然感到困惑,因為即使用戶(或Authorization請求標頭)提交了有效的身份驗證憑據......服務器如何知道它們是有效的?
在我遇到的每篇討論HTTP 基本身份驗證機制的檔案中,討論都沒有涉及到實際驗證憑據的點。
題:
提交的憑據如何實際驗證?
哪里是服務器比較提交憑據......什么?
獎金問題:
N.B. This is related to my main question immediately above because my use of .htaccess and queryString parameters to convey credentials (see below) renders deployment of HTTP Basic Auth entirely redundant - if I go down this route, I can convey credentials using .htaccess and queryString parameters alone and I don't need to deploy HTTP Basic Auth at all.
As a way to circumvent the CGI/FastCGI issue, I often see variations of these .htaccess lines cited:
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
or
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization},last]
or
SetEnvIf Authorization . HTTP_AUTHORIZATION=$0
though my attempts to get any of these methods to populate PHP Environment Variables with the credentials have all proven unsuccessful.
Instead, I have deployed the following (using queryString parameters instead of Environment variables), successfully:
# WRITE HTTP BASIC AUTHENTICATION CREDENTIALS TO QUERY STRING
RewriteCond %{HTTP:Authorization} [NC]
RewriteCond %{QUERY_STRING} ^basicauth=login$ [NC]
RewriteRule ^my-document.php https://example.com/my-document.php?basicauth=login-submitted&credentials=%{HTTP:Authorization} [NC,L]
which appends the credentials as queryString parameters.
I am not unhappy with my own mod_rewrite solution above, but I am stumped that I cannot get Environment Variables working at all.
I'm idly wondering if there is something obvious I'm missing when it comes to the latter - like... might they be switched off in my PHP Configuration?
(And, if so, which entries would I need to check in PHPInfo to confirm that they were actually switched on and receptive to values transferred to them via mod_rewrite?)
uj5u.com熱心網友回復:
解釋并未涉及實際的身份驗證,因為如何執行此操作完全取決于您。
用戶名和密碼以明文*發送給您。因此,就像有人提交帶有username和password欄位的登錄表單一樣,您可以決定如何處理它。
*:是的,它們是 base64 編碼的。但我的觀點是它們沒有經過散列或加密或類似的東西。
那么,你可能...
- 將用戶名和密碼與其他一些明文值進行比較,例如來自環境變數
- 散列密碼并將散列與某些東西進行比較,例如資料庫中的散列密碼
- 將憑據轉發到某些外部身份驗證服務
- ……?
在服務器上看起來如何的示例(此示例假定使用 node.js、Koa、koa-router、Mongoose 和 bcrypt,并且為簡化起見,它假定用戶名和密碼都不允許包含冒號):
router.get('/protectedPage', async ctx => {
const [authMethod, authData] = ctx.get('authorization')?.split(' ') ?? []
if (authMethod === 'Basic') {
try {
const decoded = Buffer.from(authData, 'base64').toString()
const [username, password] = decoded.split(':')
// Find user in database and verify password
const user = await User.findOne({ username })
if (user && await bcrypt.compare(password, user.encryptedPassword)) {
// User is authenticated now
ctx.state.user = user
}
} catch (e) {
console.error(`Failed to process auth header "${authData}"`, e)
}
}
if (ctx.state.user) {
return ctx.render('protectedPage')
} else {
return ctx.throw(401, null, {
headers: { 'WWW-Authenticate': 'Basic realm="Protected Page"' }
})
}
})
本質上,您如何使用憑據不在機制的范圍內。
(關于注銷:我通常將人們重定向到https://[email protected]或類似的東西,以便從現在開始請求將使用這個無效的用戶名和空密碼,再次導致 401。請注意,如果頁面在快取中,這將不起作用,因為無論如何都會提供快取版本,因此在這種情況下可能需要額外考慮這方面 - 可能無論如何都不應該快取經過身份驗證的頁面。)
關于“不安全”方面:如果您使用 HTTPS,它并不是真的不安全,因為“憑據以明文形式在每個請求中發送”的方面不再相關。然而,它確實提出了這個答案中概述的其他問題,最重要的是,現在明文密碼驗證應該有意設計為一個緩慢的操作以避免蠻力攻擊,但是像基本身份驗證這樣的系統必須在每個系統上執行請求,這給服務器帶來了沉重的負擔,很容易被濫用進行拒絕服務攻擊。
關于如何將授權標頭轉發給 PHP:除非以奇怪的方式配置了其他內容,否則只需要CGIPassAuth on在 Apache 的配置中進行設定即可。
From the docs:
CGIPassAuthallows scripts access to HTTP authorization headers such asAuthorization, which is required for scripts that implement HTTP Basic authentication. Normally these HTTP headers are hidden from scripts. This is to disallow scripts from seeing user ids and passwords used to access the server when HTTP Basic authentication is enabled in the web server. This directive should be used when scripts are allowed to implement HTTP Basic authentication.
Afterwards, the $_SERVER['HTTP_AUTHORIZATION'] variable should be set properly, and then PHP can also parse the header for you automatically and provide $_SERVER['PHP_AUTH_USER'] and $_SERVER['PHP_AUTH_PW'].
uj5u.com熱心網友回復:
所以這只是我的理解,但我對此非常有信心......:如果您要發送 HTTP 基本身份驗證,您將提供一個用戶名和密碼,該用戶名和密碼會自動加密為 base64 并在標頭中發送,例如:Basic ZG9kb3BhbmE6YXV0bw == ,當在另一端的標頭中收到時,它在標頭授權值中,它仍然看起來像:Basic YmFzaWM6YXV0bw== :) => 一個快速的 base64 解碼將從這里回傳: dodopana:auto - 這是用戶名:我給帖子的密碼。
到現在為止還挺好?!:) 現在,基本身份驗證已發送和接收。下一步 - 不是服務器步驟......它是 API 或端點軟體本身,因為它需要令牌或用戶名和密碼......應該在 API 供應商憑據之前驗證解密的身份驗證。
它只是通過一個加密的字串,并且所述標頭的比較和/或驗證現在在 API 軟體手中,或者我應該說 - 程式員應該驗證它......
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/322369.html
標籤:php .htaccess http-headers basic-authentication http-authentication
