Commit 8b06c4a1 authored by ibuler's avatar ibuler

[Update] 修改 认证

parent 93d1b3f1
package auth package auth
import ( import (
"cocogo/pkg/cctx"
"cocogo/pkg/i18n"
"strings" "strings"
"github.com/gliderlabs/ssh" "github.com/gliderlabs/ssh"
gossh "golang.org/x/crypto/ssh" gossh "golang.org/x/crypto/ssh"
"cocogo/pkg/cctx"
"cocogo/pkg/common" "cocogo/pkg/common"
"cocogo/pkg/i18n"
"cocogo/pkg/logger" "cocogo/pkg/logger"
"cocogo/pkg/service" "cocogo/pkg/service"
) )
...@@ -16,34 +16,34 @@ import ( ...@@ -16,34 +16,34 @@ import (
var mfaInstruction = i18n.T("Please enter 6 digits.") var mfaInstruction = i18n.T("Please enter 6 digits.")
var mfaQuestion = i18n.T("[MFA auth]: ") var mfaQuestion = i18n.T("[MFA auth]: ")
var contentKeyMFASeed = "MFASeed" const (
actionAccepted = "Accepted"
actionFailed = "Failed"
actionPartialAccepted = "Partial accepted"
)
func checkAuth(ctx ssh.Context, password, publicKey string) (res ssh.AuthResult) { func checkAuth(ctx ssh.Context, password, publicKey string) (res ssh.AuthResult) {
username := ctx.User() username := ctx.User()
remoteAddr := strings.Split(ctx.RemoteAddr().String(), ":")[0]
resp, err := service.Authenticate(username, password, publicKey, remoteAddr, "T")
authMethod := "publickey" authMethod := "publickey"
action := "Accepted" action := actionAccepted
res = ssh.AuthFailed res = ssh.AuthFailed
if password != "" { if password != "" {
authMethod = "password" authMethod = "password"
} }
if err != nil { remoteAddr := strings.Split(ctx.RemoteAddr().String(), ":")[0]
action = "Failed"
} else if resp.Seed != "" && resp.Token == "" { resp, err := service.Authenticate(username, password, publicKey, remoteAddr, "T")
ctx.SetValue(contentKeyMFASeed, resp.Seed) if err != nil {
res = ssh.AuthPartiallySuccessful action = actionFailed
} else { logger.Infof("%s %s for %s from %s", action, authMethod, username, remoteAddr)
res = ssh.AuthSuccessful return
} }
if resp != nil { if resp != nil {
switch resp.User.IsMFA { switch resp.User.OTPLevel {
case 0: case 0:
res = ssh.AuthSuccessful res = ssh.AuthSuccessful
case 1: case 1, 2:
res = ssh.AuthPartiallySuccessful action = actionPartialAccepted
case 2:
res = ssh.AuthPartiallySuccessful res = ssh.AuthPartiallySuccessful
default: default:
} }
...@@ -51,14 +51,12 @@ func checkAuth(ctx ssh.Context, password, publicKey string) (res ssh.AuthResult) ...@@ -51,14 +51,12 @@ func checkAuth(ctx ssh.Context, password, publicKey string) (res ssh.AuthResult)
ctx.SetValue(cctx.ContextKeySeed, resp.Seed) ctx.SetValue(cctx.ContextKeySeed, resp.Seed)
ctx.SetValue(cctx.ContextKeyToken, resp.Token) ctx.SetValue(cctx.ContextKeyToken, resp.Token)
} }
logger.Infof("%s %s for %s from %s", action, authMethod, username, remoteAddr) logger.Infof("%s %s for %s from %s", action, authMethod, username, remoteAddr)
return res return res
} }
func CheckUserPassword(ctx ssh.Context, password string) ssh.AuthResult { func CheckUserPassword(ctx ssh.Context, password string) ssh.AuthResult {
res := checkAuth(ctx, password, "") return checkAuth(ctx, password, "")
return res
} }
func CheckUserPublicKey(ctx ssh.Context, key ssh.PublicKey) ssh.AuthResult { func CheckUserPublicKey(ctx ssh.Context, key ssh.PublicKey) ssh.AuthResult {
...@@ -67,32 +65,40 @@ func CheckUserPublicKey(ctx ssh.Context, key ssh.PublicKey) ssh.AuthResult { ...@@ -67,32 +65,40 @@ func CheckUserPublicKey(ctx ssh.Context, key ssh.PublicKey) ssh.AuthResult {
return checkAuth(ctx, "", publicKey) return checkAuth(ctx, "", publicKey)
} }
func CheckMFA(ctx ssh.Context, challenger gossh.KeyboardInteractiveChallenge) ssh.AuthResult { func CheckMFA(ctx ssh.Context, challenger gossh.KeyboardInteractiveChallenge) (res ssh.AuthResult) {
username := ctx.User() username := ctx.User()
remoteAddr := strings.Split(ctx.RemoteAddr().String(), ":")[0]
res = ssh.AuthFailed
defer func() {
authMethod := "MFA"
if res == ssh.AuthSuccessful {
action := actionAccepted
logger.Infof("%s %s for %s from %s", action, authMethod, username, remoteAddr)
} else {
action := actionFailed
logger.Errorf("%s %s for %s from %s", action, authMethod, username, remoteAddr)
}
}()
answers, err := challenger(username, mfaInstruction, []string{mfaQuestion}, []bool{true}) answers, err := challenger(username, mfaInstruction, []string{mfaQuestion}, []bool{true})
if err != nil { if err != nil || len(answers) != 1 {
return ssh.AuthFailed return
}
if len(answers) != 1 {
return ssh.AuthFailed
} }
mfaCode := answers[0] mfaCode := answers[0]
seed, ok := ctx.Value(contentKeyMFASeed).(string) seed, ok := ctx.Value(cctx.ContextKeySeed).(string)
if !ok { if !ok {
logger.Error("Mfa Auth failed, may be user password or publickey auth failed") logger.Error("Mfa Auth failed, may be user password or publickey auth failed")
return ssh.AuthFailed return
} }
resp, err := service.CheckUserOTP(seed, mfaCode) resp, err := service.CheckUserOTP(seed, mfaCode)
if err != nil { if err != nil {
logger.Error("Mfa Auth failed: ", err) logger.Error("Mfa Auth failed: ", err)
return ssh.AuthFailed return
} }
if resp.Token != "" { if resp.Token != "" {
return ssh.AuthSuccessful res = ssh.AuthSuccessful
return
} }
return ssh.AuthFailed return
} }
func CheckUserNeedMFA(ctx ssh.Context) (methods []string) { func CheckUserNeedMFA(ctx ssh.Context) (methods []string) {
......
...@@ -85,7 +85,7 @@ func (c *Client) parseUrlQuery(url string, params []map[string]string) string { ...@@ -85,7 +85,7 @@ func (c *Client) parseUrlQuery(url string, params []map[string]string) string {
return url return url
} }
func (c *Client) ParseUrl(url string, params []map[string]string) string { func (c *Client) parseUrl(url string, params []map[string]string) string {
url = c.parseUrlQuery(url, params) url = c.parseUrlQuery(url, params)
if c.BaseHost != "" { if c.BaseHost != "" {
url = strings.TrimRight(c.BaseHost, "/") + url url = strings.TrimRight(c.BaseHost, "/") + url
...@@ -126,7 +126,7 @@ func (c *Client) SetReqHeaders(req *http.Request) { ...@@ -126,7 +126,7 @@ func (c *Client) SetReqHeaders(req *http.Request) {
} }
func (c *Client) NewRequest(method, url string, body interface{}, params []map[string]string) (req *http.Request, err error) { func (c *Client) NewRequest(method, url string, body interface{}, params []map[string]string) (req *http.Request, err error) {
url = c.ParseUrl(url, params) url = c.parseUrl(url, params)
reader, err := c.marshalData(body) reader, err := c.marshalData(body)
if err != nil { if err != nil {
return return
......
This diff is collapsed.
...@@ -7,7 +7,7 @@ type Terminal struct { ...@@ -7,7 +7,7 @@ type Terminal struct {
Id string `json:"id"` Id string `json:"id"`
Name string `json:"name"` Name string `json:"name"`
AccessKey struct { AccessKey struct {
Id string `json:"id"` ID string `json:"id"`
Secret string `json:"secret"` Secret string `json:"secret"`
} `json:"access_key"` } `json:"access_key"`
} `json:"service_account"` } `json:"service_account"`
......
...@@ -25,15 +25,14 @@ type AuthResponse struct { ...@@ -25,15 +25,14 @@ type AuthResponse struct {
} }
type User struct { type User struct {
Id string `json:"id"` ID string `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Username string `json:"username"` Username string `json:"username"`
Email string `json:"email"` Email string `json:"email"`
OTPLevel int `json:"otp_level"`
Role string `json:"role"` Role string `json:"role"`
IsValid bool `json:"is_valid"` IsValid bool `json:"is_valid"`
IsActive bool `json:"is_active"` IsActive bool `json:"is_active"`
IsMFA int `json:"otp_level"` OTPLevel int `json:"otp_level"`
} }
type TokenUser struct { type TokenUser struct {
......
...@@ -20,7 +20,7 @@ var ( ...@@ -20,7 +20,7 @@ var (
) )
type AccessKey struct { type AccessKey struct {
Id string ID string
Secret string Secret string
Path string Path string
Value string Value string
...@@ -29,7 +29,7 @@ type AccessKey struct { ...@@ -29,7 +29,7 @@ type AccessKey struct {
func (ak AccessKey) Sign() (string, string) { func (ak AccessKey) Sign() (string, string) {
date := common.HTTPGMTDate() date := common.HTTPGMTDate()
signature := common.MakeSignature(ak.Secret, date) signature := common.MakeSignature(ak.Secret, date)
return date, fmt.Sprintf("Sign %s:%s", ak.Id, signature) return date, fmt.Sprintf("Sign %s:%s", ak.ID, signature)
} }
func (ak *AccessKey) LoadAccessKeyFromStr(key string) error { func (ak *AccessKey) LoadAccessKeyFromStr(key string) error {
...@@ -40,7 +40,7 @@ func (ak *AccessKey) LoadAccessKeyFromStr(key string) error { ...@@ -40,7 +40,7 @@ func (ak *AccessKey) LoadAccessKeyFromStr(key string) error {
if len(keySlice) != 2 { if len(keySlice) != 2 {
return AccessKeyInvalid return AccessKeyInvalid
} }
ak.Id = keySlice[0] ak.ID = keySlice[0]
ak.Secret = keySlice[1] ak.Secret = keySlice[1]
return nil return nil
} }
...@@ -74,7 +74,7 @@ func (ak *AccessKey) SaveToFile() error { ...@@ -74,7 +74,7 @@ func (ak *AccessKey) SaveToFile() error {
if err != nil { if err != nil {
return err return err
} }
_, err = f.WriteString(fmt.Sprintf("%s:%s", ak.Id, ak.Secret)) _, err = f.WriteString(fmt.Sprintf("%s:%s", ak.ID, ak.Secret))
if err != nil { if err != nil {
logger.Error(err) logger.Error(err)
} }
...@@ -92,7 +92,7 @@ func (ak *AccessKey) Register(times int) error { ...@@ -92,7 +92,7 @@ func (ak *AccessKey) Register(times int) error {
logger.Error(msg) logger.Error(msg)
os.Exit(1) os.Exit(1)
} }
ak.Id = res.ServiceAccount.AccessKey.Id ak.ID = res.ServiceAccount.AccessKey.ID
ak.Secret = res.ServiceAccount.AccessKey.Secret ak.Secret = res.ServiceAccount.AccessKey.Secret
return nil return nil
} }
......
...@@ -7,12 +7,12 @@ import ( ...@@ -7,12 +7,12 @@ import (
"cocogo/pkg/model" "cocogo/pkg/model"
) )
func GetUserAssets(userId, cachePolicy string) (assets model.AssetList) { func GetUserAssets(userID, cachePolicy string) (assets model.AssetList) {
if cachePolicy == "" { if cachePolicy == "" {
cachePolicy = "0" cachePolicy = "0"
} }
payload := map[string]string{"cache_policy": cachePolicy} payload := map[string]string{"cache_policy": cachePolicy}
Url := fmt.Sprintf(UserAssetsURL, userId) Url := fmt.Sprintf(UserAssetsURL, userID)
err := authClient.Get(Url, &assets, payload) err := authClient.Get(Url, &assets, payload)
if err != nil { if err != nil {
logger.Error("GetUserAssets---err") logger.Error("GetUserAssets---err")
......
...@@ -23,8 +23,7 @@ func Authenticate(username, password, publicKey, remoteAddr, loginType string) ( ...@@ -23,8 +23,7 @@ func Authenticate(username, password, publicKey, remoteAddr, loginType string) (
"remote_addr": remoteAddr, "remote_addr": remoteAddr,
"login_type": loginType, "login_type": loginType,
} }
Url := client.ParseUrl(UserAuthURL, nil) err = client.Post(UserAuthURL, data, &resp)
err = client.Post(Url, data, &resp)
if err != nil { if err != nil {
logger.Error(err) logger.Error(err)
...@@ -32,33 +31,8 @@ func Authenticate(username, password, publicKey, remoteAddr, loginType string) ( ...@@ -32,33 +31,8 @@ func Authenticate(username, password, publicKey, remoteAddr, loginType string) (
return return
} }
func AuthenticateMFA(seed, code, loginType string) (resp *model.AuthResponse, err error) { func GetUserProfile(userID string) (user *model.User) {
/* Url := fmt.Sprintf(UserDetailURL, userID)
data = {
'seed': seed,
'otp_code': otp_code,
'login_type': login_type,
}
*/
data := map[string]string{
"seed": seed,
"otp_code": code,
"login_type": loginType,
}
Url := client.ParseUrl(AuthMFAURL, nil)
err = client.Post(Url, data, resp)
if err != nil {
logger.Error(err)
}
return
}
func GetUserProfile(userId string) (user *model.User) {
Url := fmt.Sprintf(UserDetailURL, userId)
err := authClient.Get(Url, user) err := authClient.Get(Url, user)
if err != nil { if err != nil {
logger.Error(err) logger.Error(err)
...@@ -98,9 +72,9 @@ func CheckUserOTP(seed, code string) (resp *AuthResp, err error) { ...@@ -98,9 +72,9 @@ func CheckUserOTP(seed, code string) (resp *AuthResp, err error) {
return return
} }
func CheckUserCookie(sessionId, csrfToken string) (user *model.User) { func CheckUserCookie(sessionID, csrfToken string) (user *model.User) {
client.SetCookie("csrftoken", csrfToken) client.SetCookie("csrftoken", csrfToken)
client.SetCookie("sessionid", sessionId) client.SetCookie("sessionid", sessionID)
err := client.Get(UserProfileURL, &user) err := client.Get(UserProfileURL, &user)
if err != nil { if err != nil {
logger.Error(err) logger.Error(err)
......
...@@ -28,7 +28,7 @@ func AuthDecorator(handler http.HandlerFunc) http.HandlerFunc { ...@@ -28,7 +28,7 @@ func AuthDecorator(handler http.HandlerFunc) http.HandlerFunc {
} }
} }
user := service.CheckUserCookie(sessionid, csrfToken) user := service.CheckUserCookie(sessionid, csrfToken)
if user.Id == "" { if user.ID == "" {
// Todo: 构建login的url // Todo: 构建login的url
http.Redirect(responseWriter, request, "", http.StatusFound) http.Redirect(responseWriter, request, "", http.StatusFound)
return return
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment