feat: support key auto signin in beego filter

Co-authored-by: hsluoyz <3787410+hsluoyz@users.noreply.github.com>
Agent-Logs-Url: https://github.com/casdoor/casdoor/sessions/70d67577-be92-4553-9aa2-b8ccbbf35200
This commit is contained in:
copilot-swe-agent[bot]
2026-03-24 16:27:17 +00:00
parent f9217daf52
commit 942ed2e306
3 changed files with 63 additions and 0 deletions

View File

@@ -15,7 +15,9 @@
package object
import (
"crypto/subtle"
"fmt"
"time"
"github.com/casdoor/casdoor/util"
"github.com/xorm-io/core"
@@ -206,3 +208,38 @@ func GetKeyByAccessKey(accessKey string) (*Key, error) {
}
return nil, nil
}
func ResolveSubjectByKey(accessKey, accessSecret string) (string, error) {
key, err := GetKeyByAccessKey(accessKey)
if err != nil {
return "", err
}
if key == nil || subtle.ConstantTimeCompare([]byte(key.AccessSecret), []byte(accessSecret)) != 1 {
return "", fmt.Errorf("invalid key credentials")
}
if key.State != "Active" {
return "", fmt.Errorf("key is not active")
}
if key.ExpireTime != "" {
expireTimeObj, err := time.Parse(time.RFC3339, key.ExpireTime)
if err != nil {
return "", err
}
if time.Now().After(expireTimeObj) {
return "", fmt.Errorf("key has expired")
}
}
switch key.Type {
case "User":
return util.GetId(key.Owner, key.User), nil
case "Application":
return fmt.Sprintf("app/%s", key.Application), nil
case "Organization":
return fmt.Sprintf("org/%s", key.Organization), nil
default:
return util.GetId(key.Owner, key.Name), nil
}
}

View File

@@ -97,6 +97,17 @@ func AutoSigninFilter(ctx *context.Context) {
return
}
// "/page?accessKey=123&accessSecret=456"
userId, err = getUsernameByApiKey(ctx)
if err != nil {
responseError(ctx, err.Error())
return
}
if userId != "" {
setSessionUser(ctx, userId)
return
}
// "/page?username=built-in/admin&password=123"
userId = ctx.Input.Query("username")
password := ctx.Input.Query("password")

View File

@@ -109,6 +109,21 @@ func denyMcpRequest(ctx *context.Context) {
_ = ctx.Output.JSON(resp, true, false)
}
func getUsernameByApiKey(ctx *context.Context) (string, error) {
accessKey := ctx.Input.Query("accessKey")
accessSecret := ctx.Input.Query("accessSecret")
if accessKey == "" || accessSecret == "" {
return "", nil
}
userId, err := object.ResolveSubjectByKey(accessKey, accessSecret)
if err != nil {
return "", err
}
return userId, nil
}
func getUsernameByClientIdSecret(ctx *context.Context) (string, error) {
clientId, clientSecret, ok := ctx.Request.BasicAuth()
if !ok {