Я пытаюсь понять, как получить клиентские сертификаты на веб-сервере Go. Вот код сервера:Как получить клиентские сертификаты на сервере Go HTTPS
package main
import (
"log"
"net/http"
"net/http/httputil"
)
func defaultHandler(w http.ResponseWriter, r *http.Request) {
dump, err := httputil.DumpRequest(r, true)
log.Println("HTTP request", r, string(dump), err)
log.Println("HTTP TLS", r.TLS, string(r.TLS.TLSUnique))
certs := r.TLS.PeerCertificates
log.Println("HTTP CERTS", certs)
w.WriteHeader(http.StatusMethodNotAllowed)
w.Write([]byte("Hello"))
}
func main() {
http.HandleFunc("/", defaultHandler)
http.ListenAndServeTLS(":8080", "server.crt", "server.key", nil)
}
и здесь код клиента
package main
import (
"crypto/tls"
"io/ioutil"
"log"
"net/http"
"os"
)
func HttpClient() (client *http.Client) {
uckey := os.Getenv("X509_USER_KEY")
ucert := os.Getenv("X509_USER_CERT")
x509cert, err := tls.LoadX509KeyPair(ucert, uckey)
if err != nil {
panic(err.Error())
}
certs := []tls.Certificate{x509cert}
if len(certs) == 0 {
client = &http.Client{}
return
}
tr := &http.Transport{
TLSClientConfig: &tls.Config{Certificates: certs,
InsecureSkipVerify: true},
}
client = &http.Client{Transport: tr}
return
}
func main() {
rurl := "https://localhost:8080"
client := HttpClient()
req, err := http.NewRequest("GET", rurl, nil)
if err != nil {
log.Println("Unable to make GET request", err)
os.Exit(1)
}
req.Header.Add("Accept", "*/*")
resp, err := client.Do(req)
if err != nil {
log.Println(err)
os.Exit(1)
}
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
log.Println(string(data))
}
Если я бегу как сервер и клиент, я вижу следующие на стороне сервера:
2017/02/08 15:46:49 HTTP request &{GET/HTTP/1.1 1 1 map[User-Agent:[Go-http-client/1.1] Accept:[*/*] Accept-Encoding:[gzip]] {} 0 [] false localhost:8080 map[] map[] <nil> map[] 127.0.0.1:58941/0xc4204ef080 <nil> <nil> 0xc420014d40} GET/HTTP/1.1
Host: localhost:8080
Accept: */*
Accept-Encoding: gzip
User-Agent: Go-http-client/1.1
<nil>
2017/02/08 15:46:49 HTTP TLS &{771 true false 49195 true localhost [] [] [] [] [203 144 196 105 155 216 89 105 83 90 93 4]} ːiSZ]
2017/02/08 15:46:49 HTTP CERTS []
As вы можете видеть, что сертификаты клиента пусты.
Хотя если я вызываю локон вызов на сервер предоставления своих сертификатов, то я могу увидеть сертификаты сервера:
curl -L -k --key mykey.key --cert mycert.pem -vvv https://localhost:8080
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /opt/local/share/curl/curl-ca-bundle.crt
CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2/ECDHE-ECDSA-AES128-GCM-SHA256
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: C=US; ST=NY; L=Town; O=Bla-Bla
* start date: Feb 8 14:12:06 2017 GMT
* expire date: Feb 6 14:12:06 2027 GMT
* issuer: C=US; ST=NY; L=Ithaca; O=Cornell
* SSL certificate verify result: self signed certificate (18), continuing anyway.
> GET/HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.52.1
> Accept: */*
Как вы можете видеть SSL переговоры на месте и скручивание клиент успешно передает сертификат сервера. Мне нужно получить доступ к сертификату клиента на стороне сервера для обеспечения правильной аутентификации. Но пока я не вижу никакого сертификата клиента.
Любая помощь действительно приветствуется. Thanks, Valentin.
Вот так, спасибо. – Valentin