mirror of
https://github.com/XZB-1248/Spark
synced 2025-10-05 16:16:49 +08:00
add: hashed password support
This commit is contained in:
77
server/auth/auth.go
Normal file
77
server/auth/auth.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
@@ -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)
|
||||||
|
@@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user