go 同一个https端口实现多种认证方式

参考kube-apiserver,访问https端口时,-k允许跳过默认的证书认证,从而实现多种认证方式。

package main

import (
	"crypto/tls"
	"fmt"
	"net/http"

	klog "k8s.io/klog/v2"
)

func healthCheck(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "ok")
}

func authCheck(w http.ResponseWriter, r *http.Request) {
	token := r.Header.Get("Authorization")
	if token == "" {
		fmt.Fprintf(w, "fail")
		return
	}

	if token == "abc" {
		fmt.Fprintf(w, "ok")
	} else {
		fmt.Fprintf(w, "fail")
	}
}

func main() {
	mux := http.NewServeMux()
	mux.HandleFunc("/health", healthCheck)
	mux.HandleFunc("/auth", authCheck)

	srv := &http.Server{
		Addr:    "127.0.0.1:1000",
		Handler: mux,
		TLSConfig: &tls.Config{
			// 向客户端请求提供证书,非必须且不校验
			ClientAuth: tls.RequestClientCert,
		},
	}

	if err := srv.ListenAndServeTLS("/etc/kubernetes/pki/apiserver.crt", "/etc/kubernetes/pki/apiserver.key"); err != nil {
		klog.Fatalf("failed to listen server, err is %v", err)
	}
}
[root@node1 use-k8s-queue]# curl http://127.0.0.1:1000
Client sent an HTTP request to an HTTPS server.
[root@node1 use-k8s-queue]# curl https://127.0.0.1:1000
curl: (60) Peer's Certificate issuer is not recognized.
[root@node1 use-k8s-queue]# curl https://127.0.0.1:1000/auth
curl: (60) Peer's Certificate issuer is not recognized.
[root@node1 use-k8s-queue]# curl https://127.0.0.1:1000/health
curl: (60) Peer's Certificate issuer is not recognized.
[root@node1 use-k8s-queue]# curl https://127.0.0.1:1000/health -k
ok[root@node1 use-k8s-queue]# curl https://127.0.0.1:1000/auth -k -H 'Authorization: Bearer abc'
ok

curl -k代码实现

client := &http.Client{
	Transport: &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	},
}

如果TLSConfig中ClientAuth设置成RequireAndVerifyClientCert,那么访问https时必须通过证书认证,不允许跳过,加-k也不行。

[root@node1 use-k8s-queue]# curl https://127.0.0.1:1000/auth -k -H 'Authorization: Bearer abc'
curl: (58) NSS: client certificate not found (nickname not specified)

 

posted on 2024-02-26 09:08  王景迁  阅读(49)  评论(0)    收藏  举报

导航