You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

auth.go 2.1 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package auth
  2. import (
  3. "crypto/tls"
  4. "github.com/gin-gonic/gin"
  5. "gitlink.org.cn/cloudream/common/pkgs/logger"
  6. "gitlink.org.cn/cloudream/jcs-pub/client/internal/http/types"
  7. "gitlink.org.cn/cloudream/jcs-pub/client/sdk/signer"
  8. "gitlink.org.cn/cloudream/jcs-pub/common/ecode"
  9. )
  10. const (
  11. ClientInternalSNI = "client.jcs-pub.internal"
  12. )
  13. type Auth struct {
  14. cfg *types.Config
  15. }
  16. func New(cfg *types.Config) *Auth {
  17. return &Auth{
  18. cfg: cfg,
  19. }
  20. }
  21. func (a *Auth) TLSConfigSelector(hello *tls.ClientHelloInfo) (*tls.Config, error) {
  22. switch hello.ServerName {
  23. case ClientInternalSNI:
  24. return &tls.Config{
  25. Certificates: []tls.Certificate{a.cfg.ServerCert},
  26. ClientAuth: tls.RequireAndVerifyClientCert,
  27. ClientCAs: a.cfg.RootCA,
  28. NextProtos: []string{"h2", "http/1.1"},
  29. }, nil
  30. default:
  31. return &tls.Config{
  32. Certificates: []tls.Certificate{a.cfg.ServerCert},
  33. ClientAuth: tls.NoClientCert,
  34. NextProtos: []string{"h2", "http/1.1"},
  35. }, nil
  36. }
  37. }
  38. func (a *Auth) RejectNoCertAuth(c *gin.Context) {
  39. if c.Request.TLS == nil || c.Request.TLS.ServerName != ClientInternalSNI {
  40. c.AbortWithStatusJSON(401, types.Failed(ecode.Unauthorized, "must provide client certificate"))
  41. return
  42. }
  43. c.Next()
  44. }
  45. func (a *Auth) Presigned(c *gin.Context) {
  46. log := logger.WithField("HTTP", "Auth")
  47. accID := signer.GetAccessKeyID(c.Request.URL)
  48. if accID == "" {
  49. log.Warn("access key id not found in query string")
  50. c.AbortWithStatusJSON(401, types.Failed(ecode.Unauthorized, "access key id not found in query string"))
  51. return
  52. }
  53. cliCert := a.cfg.ClientCerts[accID]
  54. if cliCert == nil {
  55. log.Warnf("client cert not found for access key id %s", accID)
  56. c.AbortWithStatusJSON(401, types.Failed(ecode.Unauthorized, "client cert not found for access key id %s", accID))
  57. return
  58. }
  59. c.Request.URL.Host = c.Request.Host
  60. err := signer.VerifyPresigned(cliCert.VerifyKey, c.Request.Method, c.Request.URL)
  61. if err != nil {
  62. log.Warn(err.Error())
  63. c.AbortWithStatusJSON(401, types.Failed(ecode.Unauthorized, err.Error()))
  64. return
  65. }
  66. c.Next()
  67. }

本项目旨在将云际存储公共基础设施化,使个人及企业可低门槛使用高效的云际存储服务(安装开箱即用云际存储客户端即可,无需关注其他组件的部署),同时支持用户灵活便捷定制云际存储的功能细节。