为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
桃花长相依 2022-05-23 17:02:53
我目前正在编写一个 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)        }}
查看完整描述

1 回答

?
开满天机

TA贡献1786条经验 获得超13个赞

您可以创建一个可以包装 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


查看完整回答
反对 回复 2022-05-23
  • 1 回答
  • 0 关注
  • 150 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信