Go: проверка последующих HTTP-запросов с проверенным клиентом через сертификат - PullRequest
0 голосов
/ 31 марта 2020

В настоящее время я пишу 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 Ответ

1 голос
/ 31 марта 2020

Вы можете создать функцию, которая может обернуть 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.HandlerFunc s. (очевидно, только те, которые нуждаются в аутентификации):

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)
        }
}

Таким образом, ваши обработчики будут вызываться (handleAuth) только если isAuthenticated возвращает true для этого запроса, без дублирования кода во всех из них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...