PHP
·
发表于 5年以前
·
阅读量:8391
在HTTP中,基本认证(Basic access authentication)是一种用来允许网页浏览器或其他客户端程序在请求时提供用户名和口令形式的身份凭证的一种登录验证方式。
优点
基本认证的一个优点是基本上所有流行的网页浏览器都支持基本认证。基本认证很少在可公开访问的互联网网站上使用,有时候会在小的私有系统中使用(如路由器网页管理接口)。后来的机制HTTP摘要认证是为替代基本认证而开发的,允许密钥以相对安全的方式在不安全的通道上传输。
程序员和系统管理员有时会在可信网络环境中使用基本认证,使用Telnet或其他明文网络协议工具手动地测试Web服务器。这是一个麻烦的过程,但是网络上传输的内容是人可读的,以便进行诊断。
缺点
虽然基本认证非常容易实现,但该方案创建在以下的假设的基础上,即:客户端和服务器主机之间的连接是安全可信的。特别是,如果没有使用SSL/TLS这样的传输层安全的协议,那么以明文传输的密钥和口令很容易被拦截。该方案也同样没有对服务器返回的信息提供保护。
现存的浏览器保存认证信息直到标签页或浏览器被关闭,或者用户清除历史记录。HTTP没有为服务器提供一种方法指示客户端丢弃这些被缓存的密钥。这意味着服务器端在用户不关闭浏览器的情况下,并没有一种有效的方法来让用户注销。
这一个典型的HTTP客户端和HTTP服务器的对话,服务器安装在同一台计算机上(localhost),包含以下步骤:
注意:客户端有可能不需要用户交互,在第一次请求中就发送认证消息头。
package main
import (
"encoding/base64"
"fmt"
"net/http"
"strings"
)
type Auth func(string, string) bool
type handler http.HandlerFunc
func testAuth(r *http.Request, auth Auth) bool {
header := r.Header.Get("Authorization")
s := strings.SplitN(header, " ", 2)
if len(s) != 2 || s[0] != "Basic" {
return false
}
b, err := base64.StdEncoding.DecodeString(s[1])
if err != nil {
return false
}
pair := strings.SplitN(string(b), ":", 2)
if len(pair) != 2 {
return false
}
return auth(pair[0], pair[1])
}
func requireAuth(w http.ResponseWriter, r *http.Request) {
w.Header().Set("WWW-Authenticate",
"Basic realm=\"private\"")
w.WriteHeader(401)
w.Write([]byte("401 Unauthorized\n"))
}
func wrapAuth(h handler, a Auth) handler {
return func(w http.ResponseWriter, r *http.Request) {
if testAuth(r, a) {
h(w, r)
} else {
requireAuth(w, r)
}
}
}
func hello(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello secret world!")
}
func main() {
checkPassword := func(_, password string) bool {
return password == "supersecret"
}
handler1 := http.HanderFunc(hello)
handler2 := wrapAuth(handler1, checkPassword)
http.ListenAndServe(":5000", handler2)
}