|
- package auth
-
- import (
- "crypto/tls"
-
- "github.com/gin-gonic/gin"
- "gitlink.org.cn/cloudream/common/pkgs/logger"
- "gitlink.org.cn/cloudream/jcs-pub/client/internal/http/types"
- "gitlink.org.cn/cloudream/jcs-pub/client/sdk/signer"
- "gitlink.org.cn/cloudream/jcs-pub/common/ecode"
- )
-
- type ClusterProxyRequestKey string
-
- const (
- ClientInternalSNI = "client.jcs-pub.internal"
- ClusterProxyRequest ClusterProxyRequestKey = "ClusterProxyRequest"
- )
-
- type Auth struct {
- cfg *types.Config
- }
-
- func New(cfg *types.Config) *Auth {
- return &Auth{
- cfg: cfg,
- }
- }
-
- func (a *Auth) TLSConfigSelector(hello *tls.ClientHelloInfo) (*tls.Config, error) {
- switch hello.ServerName {
- case ClientInternalSNI:
- return &tls.Config{
- Certificates: []tls.Certificate{a.cfg.ServerCert},
- ClientAuth: tls.RequireAndVerifyClientCert,
- ClientCAs: a.cfg.RootCA,
- NextProtos: []string{"h2", "http/1.1"},
- }, nil
-
- default:
- return &tls.Config{
- Certificates: []tls.Certificate{a.cfg.ServerCert},
- ClientAuth: tls.NoClientCert,
- NextProtos: []string{"h2", "http/1.1"},
- }, nil
- }
- }
-
- func (a *Auth) RejectNoCertAuth(c *gin.Context) {
- if c.Request.Context().Value(ClusterProxyRequest) != nil {
- c.Next()
- return
- }
-
- if c.Request.TLS == nil || c.Request.TLS.ServerName != ClientInternalSNI {
- c.AbortWithStatusJSON(401, types.Failed(ecode.Unauthorized, "must provide client certificate"))
- return
- }
-
- c.Next()
- }
-
- func (a *Auth) Presigned(c *gin.Context) {
- log := logger.WithField("HTTP", "Auth")
-
- if c.Request.Context().Value(ClusterProxyRequest) != nil {
- c.Next()
- return
- }
-
- accID := signer.GetAccessKeyID(c.Request.URL)
- if accID == "" {
- log.Warn("access key id not found in query string")
- c.AbortWithStatusJSON(401, types.Failed(ecode.Unauthorized, "access key id not found in query string"))
- return
- }
-
- cliCert := a.cfg.ClientCerts[accID]
- if cliCert == nil {
- log.Warnf("client cert not found for access key id %s", accID)
- c.AbortWithStatusJSON(401, types.Failed(ecode.Unauthorized, "client cert not found for access key id %s", accID))
- return
- }
- c.Request.URL.Host = c.Request.Host
-
- err := signer.VerifyPresigned(cliCert.VerifyKey, c.Request.Method, c.Request.URL)
- if err != nil {
- log.Warn(err.Error())
- c.AbortWithStatusJSON(401, types.Failed(ecode.Unauthorized, err.Error()))
- return
- }
-
- c.Next()
- }
|