add: hashed password support

This commit is contained in:
XZB-1248
2022-10-15 19:40:29 +08:00
parent 9236026ffe
commit 61d6bb4152
3 changed files with 82 additions and 4 deletions

77
server/auth/auth.go Normal file
View File

@@ -0,0 +1,77 @@
package auth
import (
"crypto/sha512"
"encoding/hex"
"golang.org/x/crypto/bcrypt"
"regexp"
"strings"
"crypto/sha256"
"github.com/gin-gonic/gin"
"net/http"
)
var algorithms = map[string]func(string, string) bool{
`plain`: func(hashed, password string) bool {
return hashed == password
},
`sha256`: func(hashed, password string) bool {
hash := sha256.Sum256([]byte(password))
return hashed == hex.EncodeToString(hash[:])
},
`sha512`: func(hashed, password string) bool {
hash := sha512.Sum512([]byte(password))
return hashed == hex.EncodeToString(hash[:])
},
`bcrypt`: func(hashed, password string) bool {
return bcrypt.CompareHashAndPassword([]byte(hashed), []byte(password)) == nil
},
}
func BasicAuth(accounts map[string]string, realm string) gin.HandlerFunc {
type cipher struct {
algorithm string
password string
}
if len(realm) == 0 {
realm = `Authorization Required`
}
reg := regexp.MustCompile(`^\$([a-zA-Z0-9]+)\$([a-zA-Z0-9]+)$`)
stdAccounts := make(map[string]cipher)
for user, pass := range accounts {
if match := reg.FindStringSubmatch(pass); len(match) > 0 {
match[1] = strings.ToLower(match[1])
if _, ok := algorithms[match[1]]; ok {
stdAccounts[user] = cipher{
algorithm: match[1],
password: match[2],
}
continue
}
}
stdAccounts[user] = cipher{
algorithm: `plain`,
password: pass,
}
}
return func(c *gin.Context) {
user, pass, ok := c.Request.BasicAuth()
if !ok {
c.Header(`WWW-Authenticate`, `Basic realm=`+realm)
c.AbortWithStatus(http.StatusUnauthorized)
return
}
if account, ok := stdAccounts[user]; ok {
if check, ok := algorithms[account.algorithm]; ok {
if check(account.password, pass) {
c.Set(`user`, user)
return
}
}
}
c.Header(`WWW-Authenticate`, `Basic realm=`+realm)
c.AbortWithStatus(http.StatusUnauthorized)
}
}

View File

@@ -2,6 +2,7 @@ package main
import ( import (
"Spark/modules" "Spark/modules"
"Spark/server/auth"
"Spark/server/common" "Spark/server/common"
"Spark/server/config" "Spark/server/config"
"Spark/server/handler" "Spark/server/handler"
@@ -314,7 +315,7 @@ func checkAuth() gin.HandlerFunc {
} }
} }
auth := gin.BasicAuth(config.Config.Auth) auth := auth.BasicAuth(config.Config.Auth, ``)
return func(ctx *gin.Context) { return func(ctx *gin.Context) {
now := utils.Unix now := utils.Unix
passed := false passed := false
@@ -339,7 +340,7 @@ func checkAuth() gin.HandlerFunc {
} }
auth(ctx) auth(ctx)
user, _, _ := ctx.Request.BasicAuth() user := ctx.GetString(`user`)
if ctx.IsAborted() { if ctx.IsAborted() {
blocked.Set(addr, now+1) blocked.Set(addr, now+1)

View File

@@ -15,8 +15,8 @@ import (
) )
var ( var (
ErrEntityInvalid = errors.New(`entity is not valid`) ErrEntityInvalid = errors.New(`common.ENTITY_INVALID`)
ErrFailedVerification = errors.New(`failed to verify entity`) ErrFailedVerification = errors.New(`common.ENTITY_CHECK_FAILED`)
JSON = jsoniter.ConfigCompatibleWithStandardLibrary JSON = jsoniter.ConfigCompatibleWithStandardLibrary
) )