I have a HTTP REST service written in golang demonstrating what I'm attempting.
I want GET requests insecure and all other REST requests secured with MTLS. My implementation already uses the gin web server library so I'd like to stick with that if possible.
My issue is that I have only been able to apply the tlsConfig to both groups or neither. I've been unable to find a way to apply this at the group level.
package main
import (
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"io/ioutil"
"net/http"
"log"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
// Unprotected public router for GET requests
public := router.Group("/")
// Private router with MTLS
private := router.Group("/")
public.GET("/insecure-ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "insecure pong",
})
})
private.POST("/secure-ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "secure pong",
})
})
// Get the SystemCertPool, continue with an empty pool on error
rootCAs, err := x509.SystemCertPool()
if err != nil {
log.Fatal(err)
}
if rootCAs == nil {
rootCAs = x509.NewCertPool()
}
// Create a CA certificate pool and add cacert.pem to it
caCert, err := ioutil.ReadFile("cacert.pem")
if err != nil {
log.Fatal(err)
}
if ok := rootCAs.AppendCertsFromPEM(caCert); !ok {
err := errors.New("failed to append CA cert to local system certificate pool")
log.Fatal(err)
}
server := http.Server{
Addr: fmt.Sprintf(":%v", 8080),
Handler: router,
}
server.TLSConfig = &tls.Config{
RootCAs: rootCAs,
}
err = server.ListenAndServeTLS("certificate.crt", "privateKey.key")
if err != nil {
log.Fatal(err)
}
}