mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-03 12:30:19 +08:00
feat: add protection against attacks (#460)
Signed-off-by: 0x2a <stevesough@gmail.com>
This commit is contained in:
@ -19,6 +19,7 @@ import (
|
|||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
"xorm.io/core"
|
"xorm.io/core"
|
||||||
@ -45,6 +46,8 @@ type Token struct {
|
|||||||
Scope string `xorm:"varchar(100)" json:"scope"`
|
Scope string `xorm:"varchar(100)" json:"scope"`
|
||||||
TokenType string `xorm:"varchar(100)" json:"tokenType"`
|
TokenType string `xorm:"varchar(100)" json:"tokenType"`
|
||||||
CodeChallenge string `xorm:"varchar(100)" json:"codeChallenge"`
|
CodeChallenge string `xorm:"varchar(100)" json:"codeChallenge"`
|
||||||
|
CodeIsUsed bool `json:"codeIsUsed"`
|
||||||
|
CodeExpireIn int64 `json:"codeExpireIn"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TokenWrapper struct {
|
type TokenWrapper struct {
|
||||||
@ -119,6 +122,15 @@ func getTokenByCode(code string) *Token {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updateUsedByCode(token *Token) bool {
|
||||||
|
affected, err := adapter.Engine.Where("code=?", token.Code).Cols("code_is_used").Update(token)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return affected != 0
|
||||||
|
}
|
||||||
|
|
||||||
func GetToken(id string) *Token {
|
func GetToken(id string) *Token {
|
||||||
owner, name := util.GetOwnerAndNameFromId(id)
|
owner, name := util.GetOwnerAndNameFromId(id)
|
||||||
return getToken(owner, name)
|
return getToken(owner, name)
|
||||||
@ -238,6 +250,8 @@ func GetOAuthCode(userId string, clientId string, responseType string, redirectU
|
|||||||
Scope: scope,
|
Scope: scope,
|
||||||
TokenType: "Bearer",
|
TokenType: "Bearer",
|
||||||
CodeChallenge: challenge,
|
CodeChallenge: challenge,
|
||||||
|
CodeIsUsed: false,
|
||||||
|
CodeExpireIn: time.Now().Add(time.Minute * 5).Unix(),
|
||||||
}
|
}
|
||||||
AddToken(token)
|
AddToken(token)
|
||||||
|
|
||||||
@ -311,7 +325,29 @@ func GetOAuthToken(grantType string, clientId string, clientSecret string, code
|
|||||||
Scope: "",
|
Scope: "",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if token.CodeIsUsed {
|
||||||
|
//Resist replay attacks, if the code is reused, the token generated with this code will be deleted
|
||||||
|
DeleteToken(token)
|
||||||
|
return &TokenWrapper{
|
||||||
|
AccessToken: "error: code has been used.",
|
||||||
|
TokenType: "",
|
||||||
|
ExpiresIn: 0,
|
||||||
|
Scope: "",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if time.Now().Unix() > token.CodeExpireIn {
|
||||||
|
//can only use the code to generate a token within five minutes
|
||||||
|
DeleteToken(token)
|
||||||
|
return &TokenWrapper{
|
||||||
|
AccessToken: "error: code has expired",
|
||||||
|
TokenType: "",
|
||||||
|
ExpiresIn: 0,
|
||||||
|
Scope: "",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
token.CodeIsUsed = true
|
||||||
|
updateUsedByCode(token)
|
||||||
tokenWrapper := &TokenWrapper{
|
tokenWrapper := &TokenWrapper{
|
||||||
AccessToken: token.AccessToken,
|
AccessToken: token.AccessToken,
|
||||||
IdToken: token.AccessToken,
|
IdToken: token.AccessToken,
|
||||||
|
Reference in New Issue
Block a user