Go:通过证书使用经过身份验证的客户端验证后续的 http 请求

我目前正在编写一个 HTTP 服务器(net/http),它托管多个端点并在访问这些端点之前需要客户端身份验证(步骤 1)。成功验证后,服务器会发出一个短期令牌,然后客户端使用该令牌访问这些端点。当客户端发送令牌(通过 HTTP 标头)时,在每个处理函数的开头都有一段代码来检查客户端是否经过身份验证并且提供的令牌是有效的。我正在寻找一个可以拦截和验证客户端而不是isAuthenticated(r)从每个端点函数调用的钩子/包装器。


func getMyEndpoint(w http.ResponseWriter, r *http.Request) {

        if valid := isAuthenticated(r); !valid {

            w.WriteHeader(http.StatusUnauthorized)

            io.WriteString(w, "Invalid token or Client not authenticated."

            return

        }

        ...

}


func server() {


        http.HandleFunc("/login", clientLoginWithCertAuth)

        http.HandleFunc("/endpoint1", getMyEndpoint)

        http.HandleFunc("/endpoint2", putMyEndpoint)


        server := &http.Server{

                Addr: ":443",

                TLSConfig: &tls.Config{

                        ClientCAs:  caCertPool,

                        ClientAuth: tls.VerifyClientCertIfGiven,

                },

        }


        if err := server.ListenAndServeTLS("cert.pem", "key.pem"); err != nil {

            panic(err)

        }

}


桃花长相依
浏览 151回答 1
1回答

开满天机

您可以创建一个可以包装 a 的函数http.HandlerFunc,例如:func handleAuth(f http.HandlerFunc) http.HandlerFunc {    return func(w http.ResponseWriter, r *http.Request) {        if valid := isAuthenticated(r); !valid {            w.WriteHeader(http.StatusUnauthorized)            io.WriteString(w, "Invalid token or Client not authenticated.")            return // this return is *very* important        }        // Now call the actual handler, which is authenticated        f(w, r)    }}现在您还需要注册您的处理程序以通过将其包装在您的其他http.HandlerFuncs 周围来使用它(显然只有那些需要身份验证的):func server() {        // No authentication for /login        http.HandleFunc("/login", clientLoginWithCertAuth)        // Authentication required        http.HandleFunc("/endpoint1", handleAuth(getMyEndpoint))        http.HandleFunc("/endpoint2", handleAuth(putMyEndpoint))        server := &http.Server{                Addr: ":443",                TLSConfig: &tls.Config{                        ClientCAs:  caCertPool,                        ClientAuth: tls.VerifyClientCertIfGiven,                },        }        if err := server.ListenAndServeTLS("cert.pem", "key.pem"); err != nil {            panic(err)        }}这样,您的处理程序仅在返回该请求时才被调用 (by handleAuth) ,而不会在所有处理程序中复制代码。isAuthenticatedtrue
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go